Mobile native Wearable native

Managing Signals and Messages

Edje objects have 2 communication interfaces between the application logic (code) and GUI (theme). You can either emit a signal from the code to the theme, or create handles for the signals emitted from the theme. Signals are identified by strings. With Edje messages, you can communicate values, such as strings, float numbers, and integer numbers. Messages can also be identified by integer numbers.

Signals

You can emit signals from code to a theme, or create handles for the signals emitted from themes. Signals are identified by strings.

Using signals in the EDC file is simple. Create a program and set the signal name to the signal attribute.

group 
{ 
   name: "main";
   parts 
   {
      part 
      { 
         name: "rect1";
         type: RECT;
         description 
         { 
            state: "default" 0.0;
            min: 100 100;
            max: 100 100;
            color: 255 0 0 255;
         }
         description 
         { 
            state: "default" 1.0;
            min: 100 100;
            max: 100 100;
            color: 0 0 255 255;
         }
      }
      part 
      { 
         name: "swallow.check";
         type: SWALLOW;
         description 
         { 
            state: "default" 0.0;
            align: 0.5 0.0;
            rel2 
            {
               relative: 0.0 0.0;
               to_x: "swallow.slider_ver";
            }
         }
      }
   }
   programs 
   {
      program 
      { 
         name: "to_default_0";
         signal: "to,state,default,0";
         action: STATE_SET "default" 0.00;
         transition: ACCELERATE 0.5 CURRENT;
         target: "rect1";
      }
      program 
      { 
         name: "to_default_1";
         signal: "to,state,default,1";
         action: STATE_SET "default" 1.00;
         transition: ACCELERATE 0.5 CURRENT;
         target: "rect1";
      }
   }
}

Emitting Signals from the C Code

Create the Edje Object and widget check. When a changed event is triggered, a signal is emitted from the C code to the EDC file.

static void
create_base_gui(appdata_s *ad)
{
   char edj_path[PATH_MAX] = {0, };
   
   // Window
   ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
   elm_win_conformant_set(ad->win, EINA_TRUE);
   elm_win_autodel_set(ad->win, EINA_TRUE);

   if (elm_win_wm_rotation_supported_get(ad->win)) 
   {
      int rots[4] = { 0, 90, 180, 270 };
      elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
   }

   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);

   // Conformant
   ad->conform = elm_conformant_add(ad->win);
   elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
   elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
   evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   elm_win_resize_object_add(ad->win, ad->conform);
   evas_object_show(ad->conform);

   // Base layout
   app_get_resource(EDJ_FILE, edj_path, (int)PATH_MAX);
   ad->edje_object = edje_object_add(evas_object_evas_get(ad->win));
   edje_object_file_set(ad->edje_object, edj_path, GRP_MAIN);
   evas_object_size_hint_weight_set(ad->edje_object, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   
   ad->check = elm_check_add(ad->win);
   edje_object_part_swallow(ad->edje_object, "swallow.check", ad->check);
   evas_object_smart_callback_add(ad->check, "changed", _check_toggled, ad);

   elm_object_content_set(ad->conform, ad->edje_object);
   // Show the window
   evas_object_show(ad->win);
}

The following figure displays the result.

Figure: Signal implemented on the screen

Signal implemented on the screen

The following example implements the callback for the changed event from the widget check.

static void
_check_toggled(void *data, Evas_Object *obj, void *event_info)
{
   appdata_s *ad = data;

   if (elm_check_state_get(obj))
      edje_object_signal_emit(ad->edje_object, "to,state,default,1", "");
   else
      edje_object_signal_emit(ad->edje_object, "to,state,default,0", "");
}

The following figure displays the result.

Figure: Widget check status changed

Widget check status changed

Messages

Edje messages are used for communication between code and a given Edje object's theme. With messages, you can communicate values, such as strings, float numbers, and integer numbers. Messages can also be identified by integer numbers.

In the following example, the rect1 part is made draggable and 2 sliders added to change the part position.

group 
{ 
   name: "main";
   parts 
   {
      part 
      { 
         name: "drag_area";
         type: RECT;
         description 
         { 
            state: "default" 0.0;
            rel1 
            {
               relative: 0.0 1.0;
               to_y: "swallow.check";
            }
            rel2 
            {
               relative: 0.0 0.0;
               to_x: "swallow.slider_ver";
               to_y: "swallow.slider_hor";
            }
         }
      }
      part 
      { 
         name: "rect1";
         type: RECT;
         dragable 
         {
            x: 1 1 1;
            y: 1 1 1;
            confine: "drag_area";
         }
         description 
         { 
            state: "default" 0.0;
            min: 100 100;
            max: 100 100;
            color: 255 0 0 255;
         }
         description 
         { 
            state: "default" 1.0;
            min: 100 100;
            max: 100 100;
            color: 0 0 255 255;
         }
      }
      part 
      { 
         name: "swallow.check";
         type: SWALLOW;
         description 
         { 
            state: "default" 0.0;
            align: 0.5 0.0;
            rel2 
            {
               relative: 0.0 0.0;
               to_x: "swallow.slider_ver";
            }
         }
      }
      part 
      { 
         name: "swallow.slider_ver";
         type: SWALLOW;
         description 
         { 
            state: "default" 0.0;
            align: 1.0 0.5;
            rel1 
            {
               relative: 1.0 1.0;
               to_y: "swallow.check";
            }
            rel2 
            {
               relative: 1.0 0.0;
               to_y: "swallow.slider_hor";
            }
         }
      }
      part 
      { 
         name: "swallow.slider_hor";
         type: SWALLOW;
         description 
         { 
            state: "default" 0.0;
            align: 0.5 1.0;
            rel1 
            {
               relative: 0.0 1.0;
            }
            rel2 
            {
               relative: 0.0 1.0;
               to_x: "swallow.slider_ver";
            }
         }
      }
   }
   programs 
   {
      program 
      { 
         name: "to_default_0";
         signal: "to,state,default,0";
         action: STATE_SET "default" 0.00;
         transition: ACCELERATE 0.5 CURRENT;
         target: "rect1";
      }
      program 
      { 
         name: "to_default_1";
         signal: "to,state,default,1";
         action: STATE_SET "default" 1.00;
         transition: ACCELERATE 0.5 CURRENT;
         target: "rect1";
      }
      program 
      {
         signal: "drag";
         source: "rect1";
         script 
         {
            new Float: x, Float: y;
            get_drag(PART:"rect1", x, y);
            send_message(MSG_FLOAT, 2, x);
            send_message(MSG_FLOAT, 3, y);
         }
      }
   }
}

Add the sliders:

ad->slider_ver = elm_slider_add(ad->win);
edje_object_part_swallow(ad->edje_object, "swallow.slider_ver", ad->slider_ver);
elm_slider_horizontal_set(ad->slider_ver, EINA_FALSE);
evas_object_smart_callback_add(ad->slider_ver, "changed", _slider_changed, ad);

ad->slider_hor = elm_slider_add(ad->win);
evas_object_smart_callback_add(ad->slider_hor, "changed", _slider_changed, ad);

The following figure displays the result.

Figure: Sliders added

Sliders added

To handle the message in the Style, add the following script to the EDC file:

group 
{ 
   name: "main";
   script 
   {      	
      public message(Msg_Type:type, id, ...) 
      {
         if ((type == MSG_FLOAT_SET) && (id == 1)) 
         {
            new Float: x, Float: y;
            
            x = getfarg(2);
            y = getfarg(3);
            set_drag(PART:"rect1", x, y);
         }
      }
   }
}

This script is called when an incoming message is detected.

Sending Messages

Add a callback for the changed event to send a message to the Style:

static void
_slider_changed(void *data, Evas_Object *obj, void *event_info)
{
   appdata_s *ad = data;
   Edje_Message_Float_Set *msg;
   
   msg = malloc(sizeof(*msg) + 1 * sizeof(float));
   msg->count = 2;
   msg->val[0] = elm_slider_value_get(ad->slider_hor);
   msg->val[1] = elm_slider_value_get(ad->slider_ver);
   
   edje_object_message_send(ad->edje_object, EDJE_MESSAGE_FLOAT_SET, 1, msg);
   free(msg);
}

The same message can be sent in the opposite direction. To send messages in EDC script (Embryo – link to Embryo), use the sent_message() function.

program 
{
   signal: "drag";
   source: "rect1";
   script 
   {
      new Float: x, Float: y;
      get_drag(PART:"rect1", x, y);
      send_message(MSG_FLOAT, 2, x);
      send_message(MSG_FLOAT, 3, y);
   }
}

2 messages are sent using the drag signal from the rect1 part.

Add a message handler in the C code:

edje_object_message_handler_set(ad->edje_object, _message_handle, ad);

Add a callback:

static void
_message_handle(void *data, Evas_Object *obj, Edje_Message_Type type,
                int id, void *msg)
{
   Edje_Message_Float *m;
   appdata_s *ad = data;
   
   if (type != EDJE_MESSAGE_FLOAT) return;
   m = msg;
   if (id == 2) elm_slider_value_set(ad->slider_hor, m->val);
   if (id == 3) elm_slider_value_set(ad->slider_ver, m->val);
}
Go to top