fb60099a46358c85d924adae46a3878605dc5841
[framework/uifw/elementary.git] / src / edje_externals / elm.c
1 #include "Elementary.h"
2 #include "private.h"
3
4 int _elm_ext_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 <<<<<<< HEAD
40 external_signal(void *data __UNUSED__, Evas_Object *obj, const char *signal, const char *source)
41 {
42         char *_signal = strdup(signal);
43         char *p = _signal;
44         Evas_Object *content;
45
46         while((*p!='\0') && (*p!=']'))
47                 p++;
48
49
50         if((*p=='\0') || (*(p+1)!=':'))
51         {
52                 ERR("Invalid External Signal received: '%s' '%s'\n", signal, source);
53                 free(_signal);
54                 return ;
55         }
56
57         *p = '\0';
58         p+=2; //jump ']' and ':'
59
60         Edje_External_Type *type = evas_object_data_get(obj, "Edje_External_Type");
61         if (!type->content_get)
62         {
63                 ERR("external type '%s' from module '%s' does not provide content_get()",
64                                 type->module_name, type->module);
65                 free(_signal);
66                 return ;
67         }
68
69         content = type->content_get(type->data, obj, _signal);
70         free(_signal);
71         if(content)
72                 edje_object_signal_emit(content, signal + (p - _signal), source);
73 =======
74 external_signal(void *data __UNUSED__, Evas_Object *obj, const char *sig, const char *source)
75 {
76    char *_signal = strdup(sig);
77    char *p = _signal;
78    Evas_Object *content;
79
80    while((*p!='\0') && (*p!=']'))
81      p++;
82
83
84    if((*p=='\0') || (*(p+1)!=':'))
85      {
86         ERR("Invalid External Signal received: '%s' '%s'\n", sig, source);
87         free(_signal);
88         return ;
89      }
90
91    *p = '\0';
92    p+=2; //jump ']' and ':'
93
94    Edje_External_Type *type = evas_object_data_get(obj, "Edje_External_Type");
95    if (!type->content_get)
96      {
97         ERR("external type '%s' from module '%s' does not provide content_get()",
98             type->module_name, type->module);
99         free(_signal);
100         return ;
101      }
102
103    content = type->content_get(type->data, obj, _signal);
104    free(_signal);
105    if(content)
106      edje_object_signal_emit(content, sig + (p - _signal), source);
107 >>>>>>> remotes/origin/upstream
108 }
109
110 const char *
111 external_translate(void *data __UNUSED__, const char *orig)
112 {
113    // in future, mark all params as translatable and use dgettext()
114    // with "elementary" text domain here.
115    return orig;
116 }
117
118 typedef struct {
119    const char *emission;
120    const char *source;
121    Evas_Object *edje;
122 } Elm_External_Signals_Proxy_Context;
123
124 static void
125 _external_signal_proxy_free_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
126 {
127    Elm_External_Signals_Proxy_Context *ctxt = data;
128    free(ctxt);
129 }
130
131 static void
132 _external_signal_proxy_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
133 {
134    Elm_External_Signals_Proxy_Context *ctxt = data;
135    // TODO: Is it worth to check Evas_Smart_Cb_Description and do something
136    // TODO: with event_info given its description?
137    edje_object_signal_emit(ctxt->edje, ctxt->emission, ctxt->source);
138 }
139
140 Eina_Bool
141 external_common_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
142 {
143    if (!strcmp(param->name, "style"))
144      {
145         if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
146           {
147              param->s = elm_object_style_get(obj);
148              return EINA_TRUE;
149           }
150      }
151    else if (!strcmp(param->name, "disabled"))
152      {
153         if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
154           {
155              param->i = elm_object_disabled_get(obj);
156              return EINA_TRUE;
157           }
158      }
159    return EINA_FALSE;
160 }
161
162 Eina_Bool
163 external_common_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
164 {
165    if (!strcmp(param->name, "style"))
166      {
167          if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
168            {
169               elm_object_style_set(obj, param->s);
170               return EINA_TRUE;
171            }
172      }
173    else if (!strcmp(param->name, "disabled"))
174      {
175          if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
176            {
177               elm_object_disabled_set(obj, param->i);
178               return EINA_TRUE;
179            }
180      }
181    return EINA_FALSE;
182 }
183
184 void
185 external_signals_proxy(Evas_Object *obj, Evas_Object *edje, const char *part_name)
186 {
187    const Evas_Smart_Cb_Description **cls_descs, **inst_descs;
188    unsigned int cls_count, inst_count, total;
189    Elm_External_Signals_Proxy_Context *ctxt;
190
191    evas_object_smart_callbacks_descriptions_get
192      (obj, &cls_descs, &cls_count, &inst_descs, &inst_count);
193
194    total = cls_count + inst_count;
195    if (!total) return;
196    ctxt = malloc(sizeof(Elm_External_Signals_Proxy_Context) * total);
197    if (!ctxt) return;
198    evas_object_event_callback_add
199      (obj, EVAS_CALLBACK_FREE, _external_signal_proxy_free_cb, ctxt);
200
201    for (; cls_count > 0; cls_count--,  cls_descs++, ctxt++)
202      {
203         const Evas_Smart_Cb_Description *d = *cls_descs;
204         ctxt->emission = d->name;
205         ctxt->source = part_name;
206         ctxt->edje = edje;
207         evas_object_smart_callback_add
208           (obj, d->name, _external_signal_proxy_cb, ctxt);
209      }
210
211    for (; inst_count > 0; inst_count--,  inst_descs++, ctxt++)
212      {
213         const Evas_Smart_Cb_Description *d = *inst_descs;
214         ctxt->emission = d->name;
215         ctxt->source = part_name;
216         ctxt->edje = edje;
217         evas_object_smart_callback_add
218           (obj, d->name, _external_signal_proxy_cb, ctxt);
219      }
220    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
221                                   _external_obj_del, NULL);
222 }
223
224 void
225 external_common_params_parse(void *mem, void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
226 {
227    Elm_Params *p;
228    const Eina_List *l;
229    Edje_External_Param *param;
230
231    p = mem;
232    EINA_LIST_FOREACH(params, l, param)
233      {
234         if (!strcmp(param->name, "style"))
235           p->style = eina_stringshare_add(param->s);
236         else if (!strcmp(param->name, "disabled"))
237           {
238              p->disabled = param->i;
239              p->disabled_exists = EINA_TRUE;
240           }
241      }
242 }
243
244 void
245 external_common_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
246 {
247    const Elm_Params *p;
248    if (to_params) p = to_params;
249    else if (from_params) p = from_params;
250    else return;
251
252    if (p->style)
253       elm_object_style_set(obj, p->style);
254    if (p->disabled_exists)
255      elm_object_disabled_set(obj, p->disabled);
256 }
257
258 Evas_Object *
259 external_common_param_icon_get(Evas_Object *obj, const Edje_External_Param *p)
260 {
261    Evas_Object *edje, *parent_widget, *icon;
262    const char *file;
263
264    if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
265        return NULL;
266
267    edje = evas_object_smart_parent_get(obj);
268    edje_object_file_get(edje, &file, NULL);
269
270    parent_widget = elm_widget_parent_widget_get(obj);
271    if (!parent_widget)
272      parent_widget = edje;
273    icon = elm_icon_add(parent_widget);
274
275    if (elm_icon_file_set(icon, file, p->s))
276      return icon;
277    if (elm_icon_standard_set(icon, p->s))
278      return icon;
279
280    evas_object_del(icon);
281    return NULL;
282 }
283
284 void
285 external_common_icon_param_parse(Evas_Object **icon, Evas_Object *obj, const Eina_List *params)
286 {
287    Edje_External_Param *p = edje_external_param_find(params, "icon");
288    *icon = external_common_param_icon_get(obj, p);
289 }
290
291 Evas_Object *
292 external_common_param_edje_object_get(Evas_Object *obj, const Edje_External_Param *p)
293 {
294    Evas_Object *edje, *parent_widget, *ret;
295    const char *file;
296
297    if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
298        return NULL;
299
300    edje = evas_object_smart_parent_get(obj);
301    edje_object_file_get(edje, &file, NULL);
302
303    parent_widget = elm_widget_parent_widget_get(obj);
304    if (!parent_widget)
305      parent_widget = edje;
306
307    ret = edje_object_add(evas_object_evas_get(parent_widget));
308
309    if (edje_object_file_set(ret, file, p->s))
310      return ret;
311
312    evas_object_del(ret);
313    return NULL;
314 }
315
316 void
317 external_common_params_free(void *params)
318 {
319    Elm_Params *p = params;
320    if (p->style)
321      eina_stringshare_del(p->style);
322 }
323
324 #define DEFINE_TYPE(type_name) \
325   extern const Edje_External_Type external_##type_name##_type;
326 #include "modules.inc"
327 #undef DEFINE_TYPE
328
329 static Edje_External_Type_Info elm_external_types[] =
330 {
331 #define DEFINE_TYPE(type_name)              \
332   {"elm/"#type_name, &external_##type_name##_type},
333 #include "modules.inc"
334 #undef DEFINE_TYPE
335    {NULL, NULL}
336 };
337
338 static Eina_Bool
339 elm_mod_init(void)
340 {
341    _elm_ext_log_dom = eina_log_domain_register("elm-externals", EINA_COLOR_LIGHTBLUE);
342    edje_external_type_array_register(elm_external_types);
343    return EINA_TRUE;
344 }
345
346 static void
347 elm_mod_shutdown(void)
348 {
349    edje_external_type_array_unregister(elm_external_types);
350    if (_elm_ext_log_dom >= 0) eina_log_domain_unregister(_elm_ext_log_dom);
351    _elm_ext_log_dom = -1;
352 }
353
354 EINA_MODULE_INIT(elm_mod_init);
355 EINA_MODULE_SHUTDOWN(elm_mod_shutdown);