Merge branch 'master' into svn_merge
[framework/uifw/elementary.git] / src / edje_externals / elm.c
1 #include "Elementary.h"
2 #include "private.h"
3
4 int _elm_log_dom = -1;
5
6 static int init_count = 0;
7
8 void
9 external_elm_init(void)
10 {
11    int argc = 0;
12    char **argv = NULL;
13
14    init_count++;
15    DBG("elm_real_init\n");
16    if (init_count > 1) return;
17    ecore_app_args_get(&argc, &argv);
18    elm_init(argc, argv);
19 }
20
21 static void
22 external_elm_shutdown(void)
23 {
24    init_count--;
25    DBG("elm_real_shutdown\n");
26    if (init_count > 0) return;
27    elm_shutdown();
28 }
29
30 static void
31 _external_obj_del(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
32 {
33    evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL,
34                                   _external_obj_del);
35    external_elm_shutdown();
36 }
37
38 void
39 external_signal(void *data __UNUSED__, Evas_Object *obj, const char *signal, const char *source)
40 {
41         char *_signal = strdup(signal);
42         char *p = _signal;
43         Evas_Object *content;
44
45         while((*p!='\0') && (*p!=']'))
46                 p++;
47
48
49         if((*p=='\0') || (*(p+1)!=':'))
50         {
51                 ERR("Invalid External Signal received: '%s' '%s'\n", signal, source);
52                 free(_signal);
53                 return ;
54         }
55
56         *p = '\0';
57         p+=2; //jump ']' and ':'
58
59         Edje_External_Type *type = evas_object_data_get(obj, "Edje_External_Type");
60         if (!type->content_get)
61         {
62                 ERR("external type '%s' from module '%s' does not provide content_get()",
63                                 type->module_name, type->module);
64                 free(_signal);
65                 return ;
66         }
67
68         content = type->content_get(type->data, obj, _signal);
69         free(_signal);
70         if(content)
71                 edje_object_signal_emit(content, signal + (p - _signal), source);
72 }
73
74 const char *
75 external_translate(void *data __UNUSED__, const char *orig)
76 {
77    // in future, mark all params as translatable and use dgettext()
78    // with "elementary" text domain here.
79    return orig;
80 }
81
82 typedef struct {
83    const char *emission;
84    const char *source;
85    Evas_Object *edje;
86 } Elm_External_Signals_Proxy_Context;
87
88 static void
89 _external_signal_proxy_free_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
90 {
91    Elm_External_Signals_Proxy_Context *ctxt = data;
92    free(ctxt);
93 }
94
95 static void
96 _external_signal_proxy_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
97 {
98    Elm_External_Signals_Proxy_Context *ctxt = data;
99    // TODO: Is it worth to check Evas_Smart_Cb_Description and do something
100    // TODO: with event_info given its description?
101    edje_object_signal_emit(ctxt->edje, ctxt->emission, ctxt->source);
102 }
103
104 Eina_Bool
105 external_common_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
106 {
107    if (!strcmp(param->name, "style"))
108      {
109         if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
110           {
111              param->s = elm_object_style_get(obj);
112              return EINA_TRUE;
113           }
114      }
115    return EINA_FALSE;
116 }
117
118 Eina_Bool
119 external_common_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
120 {
121    if (!strcmp(param->name, "style"))
122      {
123          if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
124            {
125               elm_object_style_set(obj, param->s);
126               return EINA_TRUE;
127            }
128      }
129    return EINA_FALSE;
130 }
131
132 void
133 external_signals_proxy(Evas_Object *obj, Evas_Object *edje, const char *part_name)
134 {
135    const Evas_Smart_Cb_Description **cls_descs, **inst_descs;
136    unsigned int cls_count, inst_count, total;
137    Elm_External_Signals_Proxy_Context *ctxt;
138
139    evas_object_smart_callbacks_descriptions_get
140      (obj, &cls_descs, &cls_count, &inst_descs, &inst_count);
141
142    total = cls_count + inst_count;
143    if (!total) return;
144    ctxt = malloc(sizeof(Elm_External_Signals_Proxy_Context) * total);
145    if (!ctxt) return;
146    evas_object_event_callback_add
147      (obj, EVAS_CALLBACK_DEL, _external_signal_proxy_free_cb, ctxt);
148
149    for (; cls_count > 0; cls_count--,  cls_descs++, ctxt++)
150      {
151         const Evas_Smart_Cb_Description *d = *cls_descs;
152         ctxt->emission = d->name;
153         ctxt->source = part_name;
154         ctxt->edje = edje;
155         evas_object_smart_callback_add
156           (obj, d->name, _external_signal_proxy_cb, ctxt);
157      }
158
159    for (; inst_count > 0; inst_count--,  inst_descs++, ctxt++)
160      {
161         const Evas_Smart_Cb_Description *d = *inst_descs;
162         ctxt->emission = d->name;
163         ctxt->source = part_name;
164         ctxt->edje = edje;
165         evas_object_smart_callback_add
166           (obj, d->name, _external_signal_proxy_cb, ctxt);
167      }
168    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
169                                   _external_obj_del, NULL);
170 }
171
172 void
173 external_common_params_parse(void *mem, void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
174 {
175    Elm_Params *p;
176    const Eina_List *l;
177    Edje_External_Param *param;
178
179    p = mem;
180    EINA_LIST_FOREACH(params, l, param)
181      {
182         if (!strcmp(param->name, "style"))
183           {
184              p->style = eina_stringshare_add(param->s);
185              break;
186           }
187      }
188 }
189
190 void
191 external_common_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
192 {
193    const Elm_Params *p;
194    if (to_params) p = to_params;
195    else if (from_params) p = from_params;
196    else return;
197
198    if (p->style)
199       elm_object_style_set(obj, p->style);
200 }
201
202 Evas_Object *
203 external_common_param_icon_get(Evas_Object *obj, const Edje_External_Param *p)
204 {
205    Evas_Object *edje, *parent_widget, *icon;
206    const char *file;
207
208    if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
209        return NULL;
210
211    edje = evas_object_smart_parent_get(obj);
212    edje_object_file_get(edje, &file, NULL);
213
214    parent_widget = elm_widget_parent_widget_get(obj);
215    if (!parent_widget)
216      parent_widget = edje;
217    icon = elm_icon_add(parent_widget);
218
219    if (elm_icon_file_set(icon, file, p->s))
220      return icon;
221    if (elm_icon_standard_set(icon, p->s))
222      return icon;
223
224    evas_object_del(icon);
225    return NULL;
226 }
227
228 void
229 external_common_icon_param_parse(Evas_Object **icon, Evas_Object *obj, const Eina_List *params)
230 {
231    Edje_External_Param *p = edje_external_param_find(params, "icon");
232    *icon = external_common_param_icon_get(obj, p);
233 }
234
235 Evas_Object *
236 external_common_param_edje_object_get(Evas_Object *obj, const Edje_External_Param *p)
237 {
238    Evas_Object *edje, *parent_widget, *ret;
239    const char *file;
240
241    if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
242        return NULL;
243
244    edje = evas_object_smart_parent_get(obj);
245    edje_object_file_get(edje, &file, NULL);
246
247    parent_widget = elm_widget_parent_widget_get(obj);
248    if (!parent_widget)
249      parent_widget = edje;
250
251    ret = edje_object_add(evas_object_evas_get(parent_widget));
252
253    if (edje_object_file_set(ret, file, p->s))
254      return ret;
255
256    evas_object_del(ret);
257    return NULL;
258 }
259
260 void
261 external_common_params_free(void *params)
262 {
263    Elm_Params *p = params;
264    if (p->style)
265      eina_stringshare_del(p->style);
266 }
267
268 #define DEFINE_TYPE(type_name) \
269   extern const Edje_External_Type external_##type_name##_type;
270 #include "modules.inc"
271 #undef DEFINE_TYPE
272
273 static Edje_External_Type_Info elm_external_types[] =
274 {
275 #define DEFINE_TYPE(type_name)              \
276   {"elm/"#type_name, &external_##type_name##_type},
277 #include "modules.inc"
278 #undef DEFINE_TYPE
279    {NULL, NULL}
280 };
281
282 static Eina_Bool
283 elm_mod_init(void)
284 {
285    _elm_log_dom = eina_log_domain_register("elm-externals", EINA_COLOR_LIGHTBLUE);
286    edje_external_type_array_register(elm_external_types);
287    return EINA_TRUE;
288 }
289
290 static void
291 elm_mod_shutdown(void)
292 {
293    edje_external_type_array_unregister(elm_external_types);
294    if (_elm_log_dom >= 0) eina_log_domain_unregister(_elm_log_dom);
295    _elm_log_dom = -1;
296 }
297
298 EINA_MODULE_INIT(elm_mod_init);
299 EINA_MODULE_SHUTDOWN(elm_mod_shutdown);