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