aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/edje/src/lib/edje_external.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/edje/src/lib/edje_external.c')
-rw-r--r--libraries/edje/src/lib/edje_external.c559
1 files changed, 559 insertions, 0 deletions
diff --git a/libraries/edje/src/lib/edje_external.c b/libraries/edje/src/lib/edje_external.c
new file mode 100644
index 0000000..8bf6256
--- /dev/null
+++ b/libraries/edje/src/lib/edje_external.c
@@ -0,0 +1,559 @@
1#include "edje_private.h"
2
3static Eina_Hash *type_registry = NULL;
4static int init_count = 0;
5
6EAPI const char *
7edje_external_param_type_str(Edje_External_Param_Type type)
8{
9 switch (type)
10 {
11 case EDJE_EXTERNAL_PARAM_TYPE_INT:
12 return "INT";
13 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
14 return "DOUBLE";
15 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
16 return "STRING";
17 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
18 return "BOOL";
19 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
20 return "CHOICE";
21 default:
22 return "(unknown)";
23 }
24}
25
26EAPI Evas_Object *
27edje_object_part_external_object_get(const Evas_Object *obj, const char *part)
28{
29 Edje *ed;
30 Edje_Real_Part *rp;
31
32 ed = _edje_fetch(obj);
33 if ((!ed) || (!part)) return NULL;
34
35 /* Need to recalc before providing the object. */
36 _edje_recalc_do(ed);
37
38 rp = _edje_real_part_recursive_get(ed, (char *)part);
39 if (!rp)
40 {
41 ERR("no part '%s'", part);
42 return NULL;
43 }
44 if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
45 {
46 ERR("cannot get external object of a part '%s' that is not EXTERNAL",
47 rp->part->name);
48 return NULL;
49 }
50 return rp->swallowed_object;
51}
52
53EAPI Eina_Bool
54edje_object_part_external_param_set(Evas_Object *obj, const char *part, const Edje_External_Param *param)
55{
56 Edje *ed;
57 Edje_Real_Part *rp;
58
59 if ((!param) || (!param->name)) return EINA_FALSE;
60
61 ed = _edje_fetch(obj);
62 if ((!ed) || (!part)) return EINA_FALSE;
63
64 rp = _edje_real_part_recursive_get(ed, (char *)part);
65 if (!rp)
66 {
67 ERR("no part '%s'", part);
68 return EINA_FALSE;
69 }
70
71 return _edje_external_param_set(obj, rp, param);
72}
73
74EAPI Eina_Bool
75edje_object_part_external_param_get(const Evas_Object *obj, const char *part, Edje_External_Param *param)
76{
77 Edje *ed;
78 Edje_Real_Part *rp;
79
80 if ((!param) || (!param->name)) return EINA_FALSE;
81
82 ed = _edje_fetch(obj);
83 if ((!ed) || (!part)) return EINA_FALSE;
84
85 rp = _edje_real_part_recursive_get(ed, (char *)part);
86 if (!rp)
87 {
88 ERR("no part '%s'", part);
89 return EINA_FALSE;
90 }
91
92 return _edje_external_param_get(obj, rp, param);
93}
94
95
96
97EAPI Evas_Object *
98edje_object_part_external_content_get(const Evas_Object *obj, const char *part, const char *content)
99{
100 Edje *ed;
101 Edje_Real_Part *rp;
102
103 if (!content) return EINA_FALSE;
104
105 ed = _edje_fetch(obj);
106 if ((!ed) || (!part)) return EINA_FALSE;
107
108 rp = _edje_real_part_recursive_get(ed, (char *)part);
109 if (!rp)
110 {
111 ERR("no part '%s'", part);
112 return EINA_FALSE;
113 }
114
115 return _edje_external_content_get(rp->swallowed_object, content);
116}
117
118EAPI Edje_External_Param_Type
119edje_object_part_external_param_type_get(const Evas_Object *obj, const char *part, const char *param)
120{
121 Edje *ed;
122 Edje_Real_Part *rp;
123 Edje_External_Type *type;
124 Edje_External_Param_Info *info;
125
126 ed = _edje_fetch(obj);
127 if ((!ed) || (!part)) return EDJE_EXTERNAL_PARAM_TYPE_MAX;
128
129 rp = _edje_real_part_recursive_get(ed, (char *)part);
130 if (!rp)
131 {
132 ERR("no part '%s'", part);
133 return EDJE_EXTERNAL_PARAM_TYPE_MAX;
134 }
135 type = evas_object_data_get(rp->swallowed_object, "Edje_External_Type");
136 if (!type)
137 {
138 ERR("no external type for object %p", obj);
139 return EDJE_EXTERNAL_PARAM_TYPE_MAX;
140 }
141 if (!type->parameters_info)
142 {
143 ERR("no parameters information for external type '%s'",
144 type->module_name);
145 return EDJE_EXTERNAL_PARAM_TYPE_MAX;
146 }
147 for (info = type->parameters_info; info->name; info++)
148 if (strcmp(info->name, param) == 0)
149 return info->type;
150
151 ERR("no parameter '%s' external type '%s'", param, type->module_name);
152 return EDJE_EXTERNAL_PARAM_TYPE_MAX;
153}
154
155
156EAPI Eina_Bool
157edje_external_type_register(const char *type_name, const Edje_External_Type *type_info)
158{
159 if (!type_name)
160 return EINA_FALSE;
161 if (!type_info)
162 return EINA_FALSE;
163
164 if (type_info->abi_version != EDJE_EXTERNAL_TYPE_ABI_VERSION)
165 {
166 ERR("external type '%s' (%p) has incorrect abi version. "
167 "got %#x where %#x was expected.",
168 type_name, type_info,
169 type_info->abi_version, EDJE_EXTERNAL_TYPE_ABI_VERSION);
170 return EINA_FALSE;
171 }
172
173 if (eina_hash_find(type_registry, type_name))
174 {
175 ERR("External type '%s' already registered", type_name);
176 return EINA_FALSE;
177 }
178 return eina_hash_add(type_registry, type_name, type_info);
179}
180
181EAPI Eina_Bool
182edje_external_type_unregister(const char *type_name)
183{
184 if (!type_name)
185 return EINA_FALSE;
186 return eina_hash_del_by_key(type_registry, type_name);
187}
188
189EAPI void
190edje_external_type_array_register(const Edje_External_Type_Info *array)
191{
192 const Edje_External_Type_Info *itr;
193
194 if (!array)
195 return;
196
197 for (itr = array; itr->name; itr++)
198 {
199 if (itr->info->abi_version != EDJE_EXTERNAL_TYPE_ABI_VERSION)
200 {
201 ERR("external type '%s' (%p) has incorrect abi "
202 "version. got %#x where %#x was expected.",
203 itr->name, itr->info,
204 itr->info->abi_version, EDJE_EXTERNAL_TYPE_ABI_VERSION);
205 continue;
206 }
207
208 eina_hash_direct_add(type_registry, itr->name, itr->info);
209 }
210}
211
212EAPI void
213edje_external_type_array_unregister(const Edje_External_Type_Info *array)
214{
215 const Edje_External_Type_Info *itr;
216
217 if (!array)
218 return;
219
220 for (itr = array; itr->name; itr++)
221 eina_hash_del(type_registry, itr->name, itr->info);
222}
223
224EAPI unsigned int
225edje_external_type_abi_version_get(void)
226{
227 return EDJE_EXTERNAL_TYPE_ABI_VERSION;
228}
229
230EAPI Eina_Iterator *
231edje_external_iterator_get(void)
232{
233 return eina_hash_iterator_tuple_new(type_registry);
234}
235
236EAPI Edje_External_Param *
237edje_external_param_find(const Eina_List *params, const char *key)
238{
239 const Eina_List *l;
240 Edje_External_Param *param;
241
242 EINA_LIST_FOREACH(params, l, param)
243 if (!strcmp(param->name, key)) return param;
244
245 return NULL;
246}
247
248EAPI Eina_Bool
249edje_external_param_int_get(const Eina_List *params, const char *key, int *ret)
250{
251 Edje_External_Param *param;
252
253 if (!params) return EINA_FALSE;
254 param = edje_external_param_find(params, key);
255
256 if (param && param->type == EDJE_EXTERNAL_PARAM_TYPE_INT && ret)
257 {
258 *ret = param->i;
259 return EINA_TRUE;
260 }
261
262 return EINA_FALSE;
263}
264
265EAPI Eina_Bool
266edje_external_param_double_get(const Eina_List *params, const char *key, double *ret)
267{
268 Edje_External_Param *param;
269
270 if (!params) return EINA_FALSE;
271 param = edje_external_param_find(params, key);
272
273 if (param && param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE && ret)
274 {
275 *ret = param->d;
276 return EINA_TRUE;
277 }
278
279 return EINA_FALSE;
280}
281
282EAPI Eina_Bool
283edje_external_param_string_get(const Eina_List *params, const char *key, const char **ret)
284{
285 Edje_External_Param *param;
286
287 if (!params) return EINA_FALSE;
288 param = edje_external_param_find(params, key);
289
290 if (param && param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING && ret)
291 {
292 *ret = param->s;
293 return EINA_TRUE;
294 }
295
296 return EINA_FALSE;
297}
298
299EAPI Eina_Bool
300edje_external_param_bool_get(const Eina_List *params, const char *key, Eina_Bool *ret)
301{
302 Edje_External_Param *param;
303
304 if (!params) return EINA_FALSE;
305 param = edje_external_param_find(params, key);
306
307 if (param && param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL && ret)
308 {
309 *ret = param->i;
310 return EINA_TRUE;
311 }
312
313 return EINA_FALSE;
314}
315
316EAPI Eina_Bool
317edje_external_param_choice_get(const Eina_List *params, const char *key, const char **ret)
318{
319 Edje_External_Param *param;
320
321 if (!params) return EINA_FALSE;
322 param = edje_external_param_find(params, key);
323
324 if (param && param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE && ret)
325 {
326 *ret = param->s;
327 return EINA_TRUE;
328 }
329
330 return EINA_FALSE;
331}
332
333EAPI const Edje_External_Param_Info *
334edje_external_param_info_get(const char *type_name)
335{
336 Edje_External_Type *type;
337
338 type = eina_hash_find(type_registry, type_name);
339 if (!type)
340 return NULL;
341 return type->parameters_info;
342}
343
344EAPI const Edje_External_Type *
345edje_external_type_get(const char *type_name)
346{
347 return eina_hash_find(type_registry, type_name);
348}
349
350void
351_edje_external_init()
352{
353 if (!type_registry)
354 type_registry = eina_hash_string_superfast_new(NULL);
355
356 init_count++;
357}
358
359void
360_edje_external_shutdown()
361{
362 if (--init_count == 0)
363 {
364 eina_hash_free(type_registry);
365 type_registry = NULL;
366 }
367}
368
369Evas_Object *
370_edje_external_type_add(const char *type_name, Evas *evas, Evas_Object *parent, const Eina_List *params, const char *part_name)
371{
372 Edje_External_Type *type;
373 Evas_Object *obj;
374
375 type = eina_hash_find(type_registry, type_name);
376 if (!type)
377 {
378 ERR("external type '%s' not registered", type_name);
379 return NULL;
380 }
381
382 obj = type->add(type->data, evas, parent, params, part_name);
383 if (!obj)
384 {
385 ERR("External type '%s' returned NULL from constructor", type_name);
386 return NULL;
387 }
388
389 evas_object_data_set(obj, "Edje_External_Type", type);
390
391 return obj;
392}
393
394void
395_edje_external_signal_emit(Evas_Object *obj, const char *emission, const char *source)
396{
397 Edje_External_Type *type;
398
399 type = evas_object_data_get(obj, "Edje_External_Type");
400 if (!type)
401 {
402 ERR("External type data not found.");
403 return;
404 }
405
406 type->signal_emit(type->data, obj, emission, source);
407}
408
409Eina_Bool
410_edje_external_param_set(Evas_Object *obj, Edje_Real_Part *rp, const Edje_External_Param *param)
411{
412 Evas_Object *swallowed_object = rp->swallowed_object;
413 Edje_External_Type *type = evas_object_data_get(swallowed_object, "Edje_External_Type");
414 if (!type)
415 {
416 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
417 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
418 {
419 if ((param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING) &&
420 (!strcmp (param->name, "text")) && (obj))
421 {
422 return edje_object_part_text_set(obj, rp->part->name, param->s);
423 }
424 }
425
426 ERR("no external type for object %p", swallowed_object);
427 return EINA_FALSE;
428 }
429 if (!type->param_set)
430 {
431 ERR("external type '%s' from module '%s' does not provide param_set()",
432 type->module_name, type->module);
433 return EINA_FALSE;
434 }
435 return type->param_set(type->data, swallowed_object, param);
436}
437
438Eina_Bool
439_edje_external_param_get(const Evas_Object *obj, Edje_Real_Part *rp, Edje_External_Param *param)
440{
441 Evas_Object *swallowed_object = rp->swallowed_object;
442 Edje_External_Type *type = evas_object_data_get(swallowed_object, "Edje_External_Type");
443 if (!type)
444 {
445 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
446 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
447 {
448 const char *text;
449 param->type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
450 param->name = "text";
451 text = edje_object_part_text_get(obj, rp->part->name);
452 param->s = text;
453 return EINA_TRUE;
454 }
455
456 ERR("no external type for object %p", swallowed_object);
457 return EINA_FALSE;
458 }
459 if (!type->param_get)
460 {
461 ERR("external type '%s' from module '%s' does not provide param_get()",
462 type->module_name, type->module);
463 return EINA_FALSE;
464 }
465 return type->param_get(type->data, swallowed_object, param);
466}
467
468Evas_Object*
469_edje_external_content_get(const Evas_Object *obj, const char *content)
470{
471 Edje_External_Type *type = evas_object_data_get(obj, "Edje_External_Type");
472 if (!type)
473 {
474 ERR("no external type for object %p", obj);
475 return EINA_FALSE;
476 }
477 if (!type->content_get)
478 {
479 ERR("external type '%s' from module '%s' does not provide content_get()",
480 type->module_name, type->module);
481 return EINA_FALSE;
482 }
483 return type->content_get(type->data, obj, content);
484}
485
486void
487_edje_external_params_free(Eina_List *external_params, Eina_Bool free_strings)
488{
489 Edje_External_Param *param;
490
491 EINA_LIST_FREE(external_params, param)
492 {
493 if (free_strings)
494 {
495 if (param->name) eina_stringshare_del(param->name);
496 if (param->s) eina_stringshare_del(param->s);
497 }
498 free(param);
499 }
500}
501
502void
503_edje_external_recalc_apply(Edje *ed __UNUSED__, Edje_Real_Part *ep,
504 Edje_Calc_Params *params __UNUSED__,
505 Edje_Part_Description_Common *chosen_desc __UNUSED__)
506{
507 Edje_External_Type *type;
508 Edje_Part_Description_External *ext;
509 void *params1, *params2 = NULL;
510
511 if (!ep->swallowed_object) return;
512 type = evas_object_data_get(ep->swallowed_object, "Edje_External_Type");
513
514 if ((!type) || (!type->state_set)) return;
515
516 ext = (Edje_Part_Description_External*) ep->param1.description;
517
518 params1 = ep->param1.external_params ?
519 ep->param1.external_params : ext->external_params;
520
521 if (ep->param2 && ep->param2->description)
522 {
523 ext = (Edje_Part_Description_External*) ep->param2->description;
524
525 params2 = ep->param2->external_params ?
526 ep->param2->external_params : ext->external_params;
527 }
528
529 type->state_set(type->data, ep->swallowed_object,
530 params1, params2, ep->description_pos);
531}
532
533void *
534_edje_external_params_parse(Evas_Object *obj, const Eina_List *params)
535{
536 Edje_External_Type *type;
537
538 type = evas_object_data_get(obj, "Edje_External_Type");
539 if (!type) return NULL;
540
541 if (!type->params_parse) return NULL;
542
543 return type->params_parse(type->data, obj, params);
544}
545
546void
547_edje_external_parsed_params_free(Evas_Object *obj, void *params)
548{
549 Edje_External_Type *type;
550
551 if (!params) return;
552
553 type = evas_object_data_get(obj, "Edje_External_Type");
554 if (!type) return;
555
556 if (!type->params_free) return;
557
558 type->params_free(params);
559}