aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/edje/src/lib/edje_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/edje/src/lib/edje_util.c')
-rw-r--r--libraries/edje/src/lib/edje_util.c4317
1 files changed, 4317 insertions, 0 deletions
diff --git a/libraries/edje/src/lib/edje_util.c b/libraries/edje/src/lib/edje_util.c
new file mode 100644
index 0000000..dbb37a7
--- /dev/null
+++ b/libraries/edje/src/lib/edje_util.c
@@ -0,0 +1,4317 @@
1#include "edje_private.h"
2
3typedef struct _Edje_Box_Layout Edje_Box_Layout;
4struct _Edje_Box_Layout
5{
6 EINA_RBTREE;
7 Evas_Object_Box_Layout func;
8 void *(*layout_data_get)(void *);
9 void (*layout_data_free)(void *);
10 void *data;
11 void (*free_data)(void *);
12 char name[];
13};
14
15static Eina_Hash *_edje_color_class_hash = NULL;
16static Eina_Hash *_edje_color_class_member_hash = NULL;
17
18static Eina_Hash *_edje_text_class_hash = NULL;
19static Eina_Hash *_edje_text_class_member_hash = NULL;
20
21static Eina_Rbtree *_edje_box_layout_registry = NULL;
22
23char *_edje_fontset_append = NULL;
24FLOAT_T _edje_scale = ZERO;
25Eina_Bool _edje_password_show_last = EINA_FALSE;
26FLOAT_T _edje_password_show_last_timeout = ZERO;
27int _edje_freeze_val = 0;
28int _edje_freeze_calc_count = 0;
29Eina_List *_edje_freeze_calc_list = NULL;
30
31typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
32struct _Edje_List_Foreach_Data
33{
34 Eina_List *list;
35};
36
37typedef struct _Edje_List_Refcount Edje_List_Refcount;
38struct _Edje_List_Refcount
39{
40 EINA_REFCOUNT;
41
42 Eina_List *lookup;
43};
44
45static Eina_Bool _edje_color_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
46static Eina_Bool _edje_text_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
47static void _edje_object_image_preload_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
48static void _edje_object_signal_preload_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
49
50Edje_Real_Part *_edje_real_part_recursive_get_helper(const Edje *ed, char **path);
51
52
53static void
54_edje_class_member_direct_del(const char *class, Edje_List_Refcount *lookup, Eina_Hash *hash)
55{
56 Eina_List *members;
57
58 members = eina_hash_find(hash, class);
59 members = eina_list_remove_list(members, lookup->lookup);
60 eina_hash_set(hash, class, members);
61 free(lookup);
62}
63
64static void
65_edje_class_member_add(Edje *ed, Eina_Hash **ehash, Eina_Hash **ghash, const char *class)
66{
67 Edje_List_Refcount *lookup;
68 Eina_List *members;
69
70 if ((!ed) || (!ehash) || (!ghash) || (!class)) return;
71
72 lookup = eina_hash_find(*ehash, class);
73 if (lookup)
74 {
75 EINA_REFCOUNT_REF(lookup);
76 return;
77 }
78
79 lookup = malloc(sizeof (Edje_List_Refcount));
80 if (!lookup) return ;
81 EINA_REFCOUNT_INIT(lookup);
82
83 /* Get members list */
84 members = eina_hash_find(*ghash, class);
85
86 /* Update the member list */
87 lookup->lookup = members = eina_list_prepend(members, ed);
88
89 /* Don't loose track of members list */
90 if (!*ehash)
91 *ehash = eina_hash_string_small_new(NULL);
92 eina_hash_add(*ehash, class, lookup);
93
94 /* Reset the member list to the right pointer */
95 if (!*ghash)
96 *ghash = eina_hash_string_superfast_new(NULL);
97 eina_hash_set(*ghash, class, members);
98}
99
100static void
101_edje_class_member_del(Eina_Hash **ehash, Eina_Hash **ghash, const char *class)
102{
103 Edje_List_Refcount *lookup;
104 Eina_List *members;
105
106 if ((!ehash) || (!ghash) || (!class)) return;
107 members = eina_hash_find(*ghash, class);
108 if (!members) return;
109
110 lookup = eina_hash_find(*ehash, class);
111 if (!lookup) return ;
112
113 EINA_REFCOUNT_UNREF(lookup)
114 {
115 members = eina_list_remove_list(members, lookup->lookup);
116 eina_hash_set(*ghash, class, members);
117
118 eina_hash_del(*ehash, class, lookup);
119 free(lookup);
120 }
121}
122
123static Eina_Bool
124member_list_free(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
125{
126 eina_list_free(data);
127 return EINA_TRUE;
128}
129
130static void
131_edje_class_members_free(Eina_Hash **ghash)
132{
133 if (!ghash || !*ghash) return;
134 eina_hash_foreach(*ghash, member_list_free, NULL);
135 eina_hash_free(*ghash);
136 *ghash = NULL;
137}
138
139/************************** API Routines **************************/
140
141#define FASTFREEZE 1
142
143EAPI void
144edje_freeze(void)
145{
146#ifdef FASTFREEZE
147 _edje_freeze_val++;
148 INF("fr ++ ->%i", _edje_freeze_val);
149#else
150// FIXME: could just have a global freeze instead of per object
151// above i tried.. but this broke some things. notable e17's menus. why?
152 Eina_List *l;
153 Evas_Object *data;
154
155 EINA_LIST_FOREACH(_edje_edjes, l, data)
156 edje_object_freeze(data);
157#endif
158}
159
160#ifdef FASTFREEZE
161static void
162_edje_thaw_edje(Edje *ed)
163{
164 unsigned int i;
165
166 for (i = 0; i < ed->table_parts_size; i++)
167 {
168 Edje_Real_Part *rp;
169
170 rp = ed->table_parts[i];
171 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
172 {
173 Edje *ed2;
174
175 ed2 = _edje_fetch(rp->swallowed_object);
176 if (ed2) _edje_thaw_edje(ed2);
177 }
178 }
179 if ((ed->recalc) && (ed->freeze <= 0)) _edje_recalc_do(ed);
180}
181#endif
182
183EAPI void
184edje_thaw(void)
185{
186#ifdef FASTFREEZE
187 _edje_freeze_val--;
188 INF("fr -- ->%i", _edje_freeze_val);
189 if ((_edje_freeze_val <= 0) && (_edje_freeze_calc_count > 0))
190 {
191 Edje *ed;
192
193 _edje_freeze_calc_count = 0;
194 EINA_LIST_FREE(_edje_freeze_calc_list, ed)
195 {
196 _edje_thaw_edje(ed);
197 ed->freeze_calc = 0;
198 }
199 }
200#else
201 Evas_Object *data;
202
203// FIXME: could just have a global freeze instead of per object
204// comment as above.. why?
205 Eina_List *l;
206
207 EINA_LIST_FOREACH(_edje_edjes, l, data)
208 edje_object_thaw(data);
209#endif
210}
211
212EAPI void
213edje_fontset_append_set(const char *fonts)
214{
215 if (_edje_fontset_append)
216 free(_edje_fontset_append);
217 _edje_fontset_append = fonts ? strdup(fonts) : NULL;
218}
219
220EAPI const char *
221edje_fontset_append_get(void)
222{
223 return _edje_fontset_append;
224}
225
226EAPI void
227edje_scale_set(double scale)
228{
229 Eina_List *l;
230 Evas_Object *data;
231
232 if (_edje_scale == FROM_DOUBLE(scale)) return;
233 _edje_scale = FROM_DOUBLE(scale);
234 EINA_LIST_FOREACH(_edje_edjes, l, data)
235 edje_object_calc_force(data);
236}
237
238EAPI double
239edje_scale_get(void)
240{
241 return TO_DOUBLE(_edje_scale);
242}
243
244EAPI void
245edje_password_show_last_set(Eina_Bool password_show_last)
246{
247 if (_edje_password_show_last == password_show_last) return;
248 _edje_password_show_last = password_show_last;
249}
250
251EAPI void
252edje_password_show_last_timeout_set(double password_show_last_timeout)
253{
254 if (_edje_password_show_last_timeout == FROM_DOUBLE(password_show_last_timeout)) return;
255 _edje_password_show_last_timeout = FROM_DOUBLE(password_show_last_timeout);
256}
257
258EAPI Eina_Bool
259edje_object_scale_set(Evas_Object *obj, double scale)
260{
261 Edje *ed;
262
263 ed = _edje_fetch(obj);
264 if (!ed) return EINA_FALSE;
265 if (ed->scale == scale) return EINA_TRUE;
266 ed->scale = FROM_DOUBLE(scale);
267 edje_object_calc_force(obj);
268 return EINA_TRUE;
269}
270
271EAPI double
272edje_object_scale_get(const Evas_Object *obj)
273{
274 Edje *ed;
275
276 ed = _edje_fetch(obj);
277 if (!ed) return 0.0;
278 return TO_DOUBLE(ed->scale);
279}
280
281EAPI Eina_Bool
282edje_object_mirrored_get(const Evas_Object *obj)
283{
284 Edje *ed;
285
286 ed = _edje_fetch(obj);
287 if (!ed) return EINA_FALSE;
288
289 return ed->is_rtl;
290}
291
292void
293_edje_object_orientation_inform(Evas_Object *obj)
294{
295 if (edje_object_mirrored_get(obj))
296 edje_object_signal_emit(obj, "edje,state,rtl", "edje");
297 else
298 edje_object_signal_emit(obj, "edje,state,ltr", "edje");
299}
300
301EAPI void
302edje_object_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
303{
304 Edje *ed;
305 unsigned int i;
306
307 ed = _edje_fetch(obj);
308 if (!ed) return;
309 if (ed->is_rtl == rtl) return;
310
311 ed->is_rtl = rtl;
312
313 for (i = 0 ; i < ed->table_parts_size ; i++)
314 {
315 Edje_Real_Part *ep;
316 const char *s;
317 double v;
318
319 ep = ed->table_parts[i];
320 s = ep->param1.description->state.name,
321 v = ep->param1.description->state.value;
322 _edje_part_description_apply(ed, ep, s, v , NULL, 0.0);
323 ep->chosen_description = ep->param1.description;
324 }
325 _edje_recalc_do(ed);
326
327 _edje_object_orientation_inform(obj);
328
329 return;
330}
331
332EAPI const char *
333edje_object_data_get(const Evas_Object *obj, const char *key)
334{
335 Edje *ed;
336
337 ed = _edje_fetch(obj);
338 if ((!ed) || (!key))
339 return NULL;
340 if (!ed->collection) return NULL;
341 if (!ed->collection->data) return NULL;
342 return edje_string_get(eina_hash_find(ed->collection->data, key));
343}
344
345EAPI int
346edje_object_freeze(Evas_Object *obj)
347{
348 Edje *ed;
349 unsigned int i;
350
351 ed = _edje_fetch(obj);
352 if (!ed) return 0;
353 for (i = 0; i < ed->table_parts_size; i++)
354 {
355 Edje_Real_Part *rp;
356 rp = ed->table_parts[i];
357 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
358 edje_object_freeze(rp->swallowed_object);
359 }
360 return _edje_freeze(ed);
361}
362
363EAPI int
364edje_object_thaw(Evas_Object *obj)
365{
366 Edje *ed;
367 unsigned int i;
368
369 ed = _edje_fetch(obj);
370 if (!ed) return 0;
371 for (i = 0; i < ed->table_parts_size; i++)
372 {
373 Edje_Real_Part *rp;
374
375 rp = ed->table_parts[i];
376 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
377 edje_object_thaw(rp->swallowed_object);
378 }
379 return _edje_thaw(ed);
380}
381
382EAPI Eina_Bool
383edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3)
384{
385 Eina_List *members;
386 Edje_Color_Class *cc;
387
388 if (!color_class) return EINA_FALSE;
389
390 cc = eina_hash_find(_edje_color_class_hash, color_class);
391 if (!cc)
392 {
393 cc = calloc(1, sizeof(Edje_Color_Class));
394 if (!cc) return EINA_FALSE;
395 cc->name = eina_stringshare_add(color_class);
396 if (!cc->name)
397 {
398 free(cc);
399 return EINA_FALSE;
400 }
401 if (!_edje_color_class_hash)
402 _edje_color_class_hash = eina_hash_string_superfast_new(NULL);
403 eina_hash_add(_edje_color_class_hash, color_class, cc);
404 }
405
406 if (r < 0) r = 0;
407 else if (r > 255) r = 255;
408 if (g < 0) g = 0;
409 else if (g > 255) g = 255;
410 if (b < 0) b = 0;
411 else if (b > 255) b = 255;
412 if (a < 0) a = 0;
413 else if (a > 255) a = 255;
414 if ((cc->r == r) && (cc->g == g) &&
415 (cc->b == b) && (cc->a == a) &&
416 (cc->r2 == r2) && (cc->g2 == g2) &&
417 (cc->b2 == b2) && (cc->a2 == a2) &&
418 (cc->r3 == r3) && (cc->g3 == g3) &&
419 (cc->b3 == b3) && (cc->a3 == a3))
420 return EINA_TRUE;
421 cc->r = r;
422 cc->g = g;
423 cc->b = b;
424 cc->a = a;
425 cc->r2 = r2;
426 cc->g2 = g2;
427 cc->b2 = b2;
428 cc->a2 = a2;
429 cc->r3 = r3;
430 cc->g3 = g3;
431 cc->b3 = b3;
432 cc->a3 = a3;
433
434 members = eina_hash_find(_edje_color_class_member_hash, color_class);
435 while (members)
436 {
437 Edje *ed;
438
439 ed = eina_list_data_get(members);
440 ed->dirty = 1;
441#ifdef EDJE_CALC_CACHE
442 ed->all_part_change = 1;
443#endif
444 _edje_recalc(ed);
445 _edje_emit(ed, "color_class,set", color_class);
446 members = eina_list_next(members);
447 }
448 return EINA_TRUE;
449}
450
451EAPI Eina_Bool
452edje_color_class_get(const char *color_class, int *r, int *g, int *b, int *a, int *r2, int *g2, int *b2, int *a2, int *r3, int *g3, int *b3, int *a3)
453{
454 Edje_Color_Class *cc;
455
456 if (!color_class)
457 cc = NULL;
458 else
459 cc = eina_hash_find(_edje_color_class_hash, color_class);
460
461 if (cc)
462 {
463#define X(C) if (C) *C = cc->C
464#define S(_r, _g, _b, _a) X(_r); X(_g); X(_b); X(_a)
465 S(r, g, b, a);
466 S(r2, g2, b2, a2);
467 S(r3, g3, b3, a3);
468#undef S
469#undef X
470 return EINA_TRUE;
471 }
472 else
473 {
474#define X(C) if (C) *C = 0
475#define S(_r, _g, _b, _a) X(_r); X(_g); X(_b); X(_a)
476 S(r, g, b, a);
477 S(r2, g2, b2, a2);
478 S(r3, g3, b3, a3);
479#undef S
480#undef X
481 return EINA_FALSE;
482 }
483}
484
485void
486edje_color_class_del(const char *color_class)
487{
488 Edje_Color_Class *cc;
489 Eina_List *members;
490
491 if (!color_class) return;
492
493 cc = eina_hash_find(_edje_color_class_hash, color_class);
494 if (!cc) return;
495
496 eina_hash_del(_edje_color_class_hash, color_class, cc);
497 eina_stringshare_del(cc->name);
498 free(cc);
499
500 members = eina_hash_find(_edje_color_class_member_hash, color_class);
501 while (members)
502 {
503 Edje *ed;
504
505 ed = eina_list_data_get(members);
506 ed->dirty = 1;
507#ifdef EDJE_CALC_CACHE
508 ed->all_part_change = 1;
509#endif
510 _edje_recalc(ed);
511 _edje_emit(ed, "color_class,del", color_class);
512 members = eina_list_next(members);
513 }
514}
515
516Eina_List *
517edje_color_class_list(void)
518{
519 Edje_List_Foreach_Data fdata;
520
521 if (!_edje_color_class_member_hash) return NULL;
522
523 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
524 eina_hash_foreach(_edje_color_class_member_hash,
525 _edje_color_class_list_foreach, &fdata);
526
527 return fdata.list;
528}
529
530static Eina_Bool
531_edje_color_class_list_foreach(const Eina_Hash *hash __UNUSED__, const void *key, void *data __UNUSED__, void *fdata)
532{
533 Edje_List_Foreach_Data *fd;
534
535 fd = fdata;
536 fd->list = eina_list_append(fd->list, strdup(key));
537 return EINA_TRUE;
538}
539
540EAPI Eina_Bool
541edje_object_color_class_set(Evas_Object *obj, const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3)
542{
543 Edje *ed;
544 Eina_List *l;
545 Edje_Color_Class *cc;
546 unsigned int i;
547
548 ed = _edje_fetch(obj);
549 if ((!ed) || (!color_class)) return EINA_FALSE;
550 if (r < 0) r = 0;
551 else if (r > 255) r = 255;
552 if (g < 0) g = 0;
553 else if (g > 255) g = 255;
554 if (b < 0) b = 0;
555 else if (b > 255) b = 255;
556 if (a < 0) a = 0;
557 else if (a > 255) a = 255;
558 color_class = eina_stringshare_add(color_class);
559 if (!color_class) return EINA_FALSE;
560 EINA_LIST_FOREACH(ed->color_classes, l, cc)
561 {
562 if (cc->name == color_class)
563 {
564 eina_stringshare_del(color_class);
565
566 if ((cc->r == r) && (cc->g == g) &&
567 (cc->b == b) && (cc->a == a) &&
568 (cc->r2 == r2) && (cc->g2 == g2) &&
569 (cc->b2 == b2) && (cc->a2 == a2) &&
570 (cc->r3 == r3) && (cc->g3 == g3) &&
571 (cc->b3 == b3) && (cc->a3 == a3))
572 return EINA_TRUE;
573 cc->r = r;
574 cc->g = g;
575 cc->b = b;
576 cc->a = a;
577 cc->r2 = r2;
578 cc->g2 = g2;
579 cc->b2 = b2;
580 cc->a2 = a2;
581 cc->r3 = r3;
582 cc->g3 = g3;
583 cc->b3 = b3;
584 cc->a3 = a3;
585 ed->dirty = 1;
586#ifdef EDJE_CALC_CACHE
587 ed->all_part_change = 1;
588#endif
589 _edje_recalc(ed);
590 return EINA_TRUE;
591 }
592 }
593 cc = malloc(sizeof(Edje_Color_Class));
594 if (!cc)
595 {
596 eina_stringshare_del(color_class);
597 return EINA_FALSE;
598 }
599 cc->name = color_class;
600 cc->r = r;
601 cc->g = g;
602 cc->b = b;
603 cc->a = a;
604 cc->r2 = r2;
605 cc->g2 = g2;
606 cc->b2 = b2;
607 cc->a2 = a2;
608 cc->r3 = r3;
609 cc->g3 = g3;
610 cc->b3 = b3;
611 cc->a3 = a3;
612 ed->color_classes = eina_list_append(ed->color_classes, cc);
613 ed->dirty = 1;
614#ifdef EDJE_CALC_CACHE
615 ed->all_part_change = 1;
616#endif
617
618 for (i = 0; i < ed->table_parts_size; i++)
619 {
620 Edje_Real_Part *rp;
621
622 rp = ed->table_parts[i];
623 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
624 edje_object_color_class_set(rp->swallowed_object, color_class,
625 r, g, b, a, r2, g2, b2, a2, r3, g3, b3,
626 a3);
627 }
628
629 _edje_recalc(ed);
630 _edje_emit(ed, "color_class,set", color_class);
631 return EINA_TRUE;
632}
633
634EAPI Eina_Bool
635edje_object_color_class_get(const Evas_Object *obj, const char *color_class, int *r, int *g, int *b, int *a, int *r2, int *g2, int *b2, int *a2, int *r3, int *g3, int *b3, int *a3)
636{
637 Edje *ed = _edje_fetch(obj);
638 Edje_Color_Class *cc = _edje_color_class_find(ed, color_class);
639
640 if (cc)
641 {
642#define X(C) if (C) *C = cc->C
643#define S(_r, _g, _b, _a) X(_r); X(_g); X(_b); X(_a)
644 S(r, g, b, a);
645 S(r2, g2, b2, a2);
646 S(r3, g3, b3, a3);
647#undef S
648#undef X
649 return EINA_TRUE;
650 }
651 else
652 {
653#define X(C) if (C) *C = 0
654#define S(_r, _g, _b, _a) X(_r); X(_g); X(_b); X(_a)
655 S(r, g, b, a);
656 S(r2, g2, b2, a2);
657 S(r3, g3, b3, a3);
658#undef S
659#undef X
660 return EINA_FALSE;
661 }
662}
663
664void
665edje_object_color_class_del(Evas_Object *obj, const char *color_class)
666{
667 Edje *ed;
668 Eina_List *l;
669 Edje_Color_Class *cc = NULL;
670 unsigned int i;
671
672 if (!color_class) return;
673
674 ed = _edje_fetch(obj);
675 EINA_LIST_FOREACH(ed->color_classes, l, cc)
676 {
677 if (!strcmp(cc->name, color_class))
678 {
679 ed->color_classes = eina_list_remove(ed->color_classes, cc);
680 eina_stringshare_del(cc->name);
681 free(cc);
682 break;
683 }
684 }
685
686 for (i = 0; i < ed->table_parts_size; i++)
687 {
688 Edje_Real_Part *rp;
689
690 rp = ed->table_parts[i];
691 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
692 edje_object_color_class_del(rp->swallowed_object, color_class);
693 }
694
695 ed->dirty = 1;
696#ifdef EDJE_CALC_CACHE
697 ed->all_part_change = 1;
698#endif
699 _edje_recalc(ed);
700 _edje_emit(ed, "color_class,del", color_class);
701}
702
703EAPI Eina_Bool
704edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size)
705{
706 Eina_List *members;
707 Edje_Text_Class *tc;
708
709 if (!text_class) return EINA_FALSE;
710 if (!font) font = "";
711
712 tc = eina_hash_find(_edje_text_class_hash, text_class);
713 /* Create new text class */
714 if (!tc)
715 {
716 tc = calloc(1, sizeof(Edje_Text_Class));
717 if (!tc) return EINA_FALSE;
718 tc->name = eina_stringshare_add(text_class);
719 if (!tc->name)
720 {
721 free(tc);
722 return EINA_FALSE;
723 }
724 if (!_edje_text_class_hash) _edje_text_class_hash = eina_hash_string_superfast_new(NULL);
725 eina_hash_add(_edje_text_class_hash, text_class, tc);
726
727 tc->font = eina_stringshare_add(font);
728 tc->size = size;
729 return EINA_FALSE;
730 }
731
732 /* If the class found is the same just return */
733 if ((tc->size == size) && (tc->font) && (!strcmp(tc->font, font)))
734 return EINA_TRUE;
735
736 /* Update the class found */
737 eina_stringshare_del(tc->font);
738 tc->font = eina_stringshare_add(font);
739 if (!tc->font)
740 {
741 eina_hash_del(_edje_text_class_hash, text_class, tc);
742 free(tc);
743 return EINA_FALSE;
744 }
745 tc->size = size;
746
747 /* Tell all members of the text class to recalc */
748 members = eina_hash_find(_edje_text_class_member_hash, text_class);
749 while (members)
750 {
751 Edje *ed;
752
753 ed = eina_list_data_get(members);
754 ed->dirty = 1;
755 _edje_textblock_style_all_update(ed);
756#ifdef EDJE_CALC_CACHE
757 ed->text_part_change = 1;
758#endif
759 _edje_recalc(ed);
760 members = eina_list_next(members);
761 }
762 return EINA_TRUE;
763}
764
765void
766edje_text_class_del(const char *text_class)
767{
768 Edje_Text_Class *tc;
769 Eina_List *members;
770
771 if (!text_class) return;
772
773 tc = eina_hash_find(_edje_text_class_hash, text_class);
774 if (!tc) return;
775
776 eina_hash_del(_edje_text_class_hash, text_class, tc);
777 eina_stringshare_del(tc->name);
778 eina_stringshare_del(tc->font);
779 free(tc);
780
781 members = eina_hash_find(_edje_text_class_member_hash, text_class);
782 while (members)
783 {
784 Edje *ed;
785
786 ed = eina_list_data_get(members);
787 ed->dirty = 1;
788 _edje_textblock_style_all_update(ed);
789#ifdef EDJE_CALC_CACHE
790 ed->text_part_change = 1;
791#endif
792 _edje_recalc(ed);
793 members = eina_list_next(members);
794 }
795}
796
797Eina_List *
798edje_text_class_list(void)
799{
800 Edje_List_Foreach_Data fdata;
801
802 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
803 eina_hash_foreach(_edje_text_class_member_hash,
804 _edje_text_class_list_foreach, &fdata);
805 return fdata.list;
806}
807
808static Eina_Bool
809_edje_text_class_list_foreach(const Eina_Hash *hash __UNUSED__, const void *key, void *data __UNUSED__, void *fdata)
810{
811 Edje_List_Foreach_Data *fd;
812
813 fd = fdata;
814 fd->list = eina_list_append(fd->list, eina_stringshare_add(key));
815 return EINA_TRUE;
816}
817
818EAPI Eina_Bool
819edje_object_text_class_set(Evas_Object *obj, const char *text_class, const char *font, Evas_Font_Size size)
820{
821 Edje *ed;
822 Eina_List *l;
823 Edje_Text_Class *tc;
824 unsigned int i;
825
826 ed = _edje_fetch(obj);
827 if ((!ed) || (!text_class)) return EINA_FALSE;
828
829 /* for each text_class in the edje */
830 EINA_LIST_FOREACH(ed->text_classes, l, tc)
831 {
832 if ((tc->name) && (!strcmp(tc->name, text_class)))
833 {
834 /* Match and the same, return */
835 if ((tc->font) && (font) && (!strcmp(tc->font, font)) &&
836 (tc->size == size))
837 return EINA_TRUE;
838
839 /* No font but size is the same, return */
840 if ((!tc->font) && (!font) && (tc->size == size)) return EINA_TRUE;
841
842 /* Update new text class properties */
843 if (tc->font) eina_stringshare_del(tc->font);
844 if (font) tc->font = eina_stringshare_add(font);
845 else tc->font = NULL;
846 tc->size = size;
847
848 /* Update edje */
849 ed->dirty = 1;
850#ifdef EDJE_CALC_CACHE
851 ed->text_part_change = 1;
852#endif
853 _edje_recalc(ed);
854 return EINA_TRUE;
855 }
856 }
857
858 /* No matches, create a new text class */
859 tc = calloc(1, sizeof(Edje_Text_Class));
860 if (!tc) return EINA_FALSE;
861 tc->name = eina_stringshare_add(text_class);
862 if (!tc->name)
863 {
864 free(tc);
865 return EINA_FALSE;
866 }
867 if (font) tc->font = eina_stringshare_add(font);
868 else tc->font = NULL;
869 tc->size = size;
870
871 for (i = 0; i < ed->table_parts_size; i++)
872 {
873 Edje_Real_Part *rp;
874
875 rp = ed->table_parts[i];
876 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
877 edje_object_text_class_set(rp->swallowed_object, text_class,
878 font, size);
879 }
880
881 /* Add to edje's text class list */
882 ed->text_classes = eina_list_append(ed->text_classes, tc);
883 ed->dirty = 1;
884#ifdef EDJE_CALC_CACHE
885 ed->text_part_change = 1;
886#endif
887 _edje_textblock_style_all_update(ed);
888 _edje_recalc(ed);
889 return EINA_TRUE;
890}
891
892EAPI Eina_Bool
893edje_object_part_exists(const Evas_Object *obj, const char *part)
894{
895 Edje *ed;
896 Edje_Real_Part *rp;
897
898 ed = _edje_fetch(obj);
899 if ((!ed) || (!part)) return EINA_FALSE;
900 rp = _edje_real_part_recursive_get(ed, (char *)part);
901 if (!rp) return EINA_FALSE;
902 return EINA_TRUE;
903}
904
905EAPI const Evas_Object *
906edje_object_part_object_get(const Evas_Object *obj, const char *part)
907{
908 Edje *ed;
909 Edje_Real_Part *rp;
910
911 ed = _edje_fetch(obj);
912 if ((!ed) || (!part)) return NULL;
913
914 /* Need to recalc before providing the object. */
915 _edje_recalc_do(ed);
916
917 rp = _edje_real_part_recursive_get(ed, (char *)part);
918 if (!rp) return NULL;
919 return rp->object;
920}
921
922EAPI Eina_Bool
923edje_object_part_geometry_get(const Evas_Object *obj, const char *part, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h )
924{
925 Edje *ed;
926 Edje_Real_Part *rp;
927
928 ed = _edje_fetch(obj);
929 if ((!ed) || (!part))
930 {
931 if (x) *x = 0;
932 if (y) *y = 0;
933 if (w) *w = 0;
934 if (h) *h = 0;
935 return EINA_FALSE;
936 }
937
938 /* Need to recalc before providing the object. */
939 _edje_recalc_do(ed);
940
941 rp = _edje_real_part_recursive_get(ed, (char *)part);
942 if (!rp)
943 {
944 if (x) *x = 0;
945 if (y) *y = 0;
946 if (w) *w = 0;
947 if (h) *h = 0;
948 return EINA_FALSE;
949 }
950 if (x) *x = rp->x;
951 if (y) *y = rp->y;
952 if (w) *w = rp->w;
953 if (h) *h = rp->h;
954 return EINA_TRUE;
955}
956
957EAPI void
958edje_object_item_provider_set(Evas_Object *obj, Edje_Item_Provider_Cb func, void *data)
959{
960 Edje *ed;
961
962 ed = _edje_fetch(obj);
963 if (!ed) return;
964 ed->item_provider.func = func;
965 ed->item_provider.data = data;
966}
967
968/* FIXDOC: New Function */
969EAPI void
970edje_object_text_change_cb_set(Evas_Object *obj, Edje_Text_Change_Cb func, void *data)
971{
972 Edje *ed;
973 unsigned int i;
974
975 ed = _edje_fetch(obj);
976 if (!ed) return;
977 ed->text_change.func = func;
978 ed->text_change.data = data;
979
980 for (i = 0; i < ed->table_parts_size; i++)
981 {
982 Edje_Real_Part *rp;
983
984 rp = ed->table_parts[i];
985 if ((rp->part->type == EDJE_PART_TYPE_GROUP) && (rp->swallowed_object))
986 edje_object_text_change_cb_set(rp->swallowed_object, func, data);
987 }
988}
989
990Eina_Bool
991_edje_object_part_text_raw_set(Evas_Object *obj, Edje_Real_Part *rp, const char *part, const char *text)
992{
993 if ((!rp->text.text) && (!text))
994 return EINA_FALSE;
995 if ((rp->text.text) && (text) &&
996 (!strcmp(rp->text.text, text)))
997 return EINA_FALSE;
998 if (rp->text.text)
999 {
1000 eina_stringshare_del(rp->text.text);
1001 rp->text.text = NULL;
1002 }
1003 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1004 _edje_entry_text_markup_set(rp, text);
1005 else
1006 if (text) rp->text.text = eina_stringshare_add(text);
1007 rp->edje->dirty = 1;
1008#ifdef EDJE_CALC_CACHE
1009 rp->invalidate = 1;
1010#endif
1011 _edje_recalc(rp->edje);
1012 if (rp->edje->text_change.func)
1013 rp->edje->text_change.func(rp->edje->text_change.data, obj, part);
1014 return EINA_TRUE;
1015}
1016
1017Eina_Bool
1018_edje_object_part_text_raw_append(Evas_Object *obj, Edje_Real_Part *rp, const char *part, const char *text)
1019{
1020 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1021 _edje_entry_text_markup_append(rp, text);
1022 else if (text)
1023 {
1024 if (rp->text.text)
1025 {
1026 char *new = NULL;
1027 int len_added = strlen(text);
1028 int len_old = strlen(rp->text.text);
1029 new = malloc(len_old + len_added + 1);
1030 memcpy(new, rp->text.text, len_old);
1031 memcpy(new + len_old, text, len_added);
1032 new[len_old + len_added] = '\0';
1033 eina_stringshare_replace(&rp->text.text, new);
1034 free(new);
1035 }
1036 else
1037 {
1038 eina_stringshare_replace(&rp->text.text, text);
1039 }
1040 }
1041 rp->edje->dirty = 1;
1042#ifdef EDJE_CALC_CACHE
1043 rp->invalidate = 1;
1044#endif
1045 _edje_recalc(rp->edje);
1046 if (rp->edje->text_change.func)
1047 rp->edje->text_change.func(rp->edje->text_change.data, obj, part);
1048 return EINA_TRUE;
1049}
1050
1051EAPI Eina_Bool
1052edje_object_part_text_set(Evas_Object *obj, const char *part, const char *text)
1053{
1054 Edje *ed;
1055 Edje_Real_Part *rp;
1056
1057 ed = _edje_fetch(obj);
1058 if ((!ed) || (!part)) return EINA_FALSE;
1059 rp = _edje_real_part_recursive_get(ed, (char *)part);
1060 if (!rp) return EINA_FALSE;
1061 if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
1062 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE;
1063 return _edje_object_part_text_raw_set(obj, rp, part, text);
1064}
1065
1066EAPI const char *
1067edje_object_part_text_get(const Evas_Object *obj, const char *part)
1068{
1069 Edje *ed;
1070 Edje_Real_Part *rp;
1071
1072 ed = _edje_fetch(obj);
1073 if ((!ed) || (!part)) return NULL;
1074
1075 /* Need to recalc before providing the object. */
1076 _edje_recalc_do(ed);
1077
1078 rp = _edje_real_part_recursive_get(ed, (char *)part);
1079 if (!rp) return NULL;
1080 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1081 return _edje_entry_text_get(rp);
1082 else
1083 {
1084 if (rp->part->type == EDJE_PART_TYPE_TEXT) return rp->text.text;
1085 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1086 return evas_object_textblock_text_markup_get(rp->object);
1087 }
1088 return NULL;
1089}
1090
1091char *
1092_edje_text_escape(const char *text)
1093{
1094 Eina_Strbuf *txt;
1095 char *ret;
1096 const char *text_end;
1097 size_t text_len;
1098
1099 if (!text) return NULL;
1100
1101 txt = eina_strbuf_new();
1102 text_len = strlen(text);
1103
1104 text_end = text + text_len;
1105 while (text < text_end)
1106 {
1107 int advance;
1108 const char *escaped = evas_textblock_string_escape_get(text, &advance);
1109 if (!escaped)
1110 {
1111 eina_strbuf_append_char(txt, text[0]);
1112 advance = 1;
1113 }
1114 else
1115 eina_strbuf_append(txt, escaped);
1116
1117 text += advance;
1118 }
1119
1120 ret = eina_strbuf_string_steal(txt);
1121 eina_strbuf_free(txt);
1122 return ret;
1123}
1124
1125char *
1126_edje_text_unescape(const char *text)
1127{
1128 Eina_Strbuf *txt;
1129 char *ret;
1130 const char *text_end, *last, *escape_start;
1131 size_t text_len;
1132
1133 if (!text) return NULL;
1134
1135 txt = eina_strbuf_new();
1136 text_len = strlen(text);
1137
1138 text_end = text + text_len;
1139 last = text;
1140 escape_start = NULL;
1141 for (; text < text_end; text++)
1142 {
1143 if (*text == '&')
1144 {
1145 size_t len;
1146 const char *str;
1147
1148 if (last)
1149 {
1150 len = text - last;
1151 str = last;
1152 }
1153 else
1154 {
1155 len = text - escape_start;
1156 str = escape_start;
1157 }
1158
1159 if (len > 0)
1160 eina_strbuf_append_n(txt, str, len);
1161
1162 escape_start = text;
1163 last = NULL;
1164 }
1165 else if ((*text == ';') && (escape_start))
1166 {
1167 size_t len;
1168 const char *str = evas_textblock_escape_string_range_get(escape_start, text);
1169
1170 if (str)
1171 len = strlen(str);
1172 else
1173 {
1174 str = escape_start;
1175 len = text + 1 - escape_start;
1176 }
1177
1178 eina_strbuf_append_n(txt, str, len);
1179
1180 escape_start = NULL;
1181 last = text + 1;
1182 }
1183 }
1184
1185 if (!last && escape_start)
1186 last = escape_start;
1187
1188 if (last && (text > last))
1189 {
1190 size_t len = text - last;
1191 eina_strbuf_append_n(txt, last, len);
1192 }
1193
1194 ret = eina_strbuf_string_steal(txt);
1195 eina_strbuf_free(txt);
1196 return ret;
1197}
1198
1199EAPI Eina_Bool
1200edje_object_part_text_unescaped_set(Evas_Object *obj, const char *part, const char *text_to_escape)
1201{
1202 Edje *ed;
1203 Edje_Real_Part *rp;
1204 Eina_Bool ret = EINA_FALSE;
1205
1206 ed = _edje_fetch(obj);
1207 if ((!ed) || (!part)) return ret;
1208 rp = _edje_real_part_recursive_get(ed, part);
1209 if (!rp) return ret;
1210 if (rp->part->type == EDJE_PART_TYPE_TEXT)
1211 ret = _edje_object_part_text_raw_set(obj, rp, part, text_to_escape);
1212 else if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1213 {
1214 char *text = _edje_text_escape(text_to_escape);
1215
1216 ret = _edje_object_part_text_raw_set(obj, rp, part, text);
1217 free(text);
1218 }
1219 return ret;
1220}
1221
1222EAPI char *
1223edje_object_part_text_unescaped_get(const Evas_Object *obj, const char *part)
1224{
1225 Edje *ed;
1226 Edje_Real_Part *rp;
1227
1228 ed = _edje_fetch(obj);
1229 if ((!ed) || (!part)) return NULL;
1230
1231 /* Need to recalc before providing the object. */
1232 _edje_recalc_do(ed);
1233
1234 rp = _edje_real_part_recursive_get(ed, (char *)part);
1235 if (!rp) return NULL;
1236 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1237 {
1238 const char *t = _edje_entry_text_get(rp);
1239 return _edje_text_unescape(t);
1240 }
1241 else
1242 {
1243 if (rp->part->type == EDJE_PART_TYPE_TEXT) return strdup(rp->text.text);
1244 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1245 {
1246 const char *t = evas_object_textblock_text_markup_get(rp->object);
1247 return _edje_text_unescape(t);
1248 }
1249 }
1250 return NULL;
1251}
1252
1253EAPI const char *
1254edje_object_part_text_selection_get(const Evas_Object *obj, const char *part)
1255{
1256 Edje *ed;
1257 Edje_Real_Part *rp;
1258
1259 ed = _edje_fetch(obj);
1260 if ((!ed) || (!part)) return NULL;
1261 rp = _edje_real_part_recursive_get(ed, (char *)part);
1262 if (!rp) return NULL;
1263 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1264 return _edje_entry_selection_get(rp);
1265 return NULL;
1266}
1267
1268EAPI void
1269edje_object_part_text_select_none(const Evas_Object *obj, const char *part)
1270{
1271 Edje *ed;
1272 Edje_Real_Part *rp;
1273
1274 ed = _edje_fetch(obj);
1275 if ((!ed) || (!part)) return;
1276 rp = _edje_real_part_recursive_get(ed, (char *)part);
1277 if (!rp) return;
1278 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1279 _edje_entry_select_none(rp);
1280}
1281
1282EAPI void
1283edje_object_part_text_select_all(const Evas_Object *obj, const char *part)
1284{
1285 Edje *ed;
1286 Edje_Real_Part *rp;
1287
1288 ed = _edje_fetch(obj);
1289 if ((!ed) || (!part)) return;
1290 rp = _edje_real_part_recursive_get(ed, (char *)part);
1291 if (!rp) return;
1292 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1293 _edje_entry_select_all(rp);
1294}
1295
1296EAPI void
1297edje_object_part_text_insert(Evas_Object *obj, const char *part, const char *text)
1298{
1299 Edje *ed;
1300 Edje_Real_Part *rp;
1301
1302 ed = _edje_fetch(obj);
1303 if ((!ed) || (!part)) return;
1304 rp = _edje_real_part_recursive_get(ed, (char *)part);
1305 if (!rp) return;
1306 if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return;
1307 if (rp->part->entry_mode <= EDJE_ENTRY_EDIT_MODE_NONE) return;
1308 _edje_entry_text_markup_insert(rp, text);
1309 rp->edje->dirty = 1;
1310#ifdef EDJE_CALC_CACHE
1311 rp->invalidate = 1;
1312#endif
1313 _edje_recalc(rp->edje);
1314 if (rp->edje->text_change.func)
1315 rp->edje->text_change.func(rp->edje->text_change.data, obj, part);
1316}
1317
1318EAPI void
1319edje_object_part_text_append(Evas_Object *obj, const char *part, const char *text)
1320{
1321 Edje *ed;
1322 Edje_Real_Part *rp;
1323
1324 ed = _edje_fetch(obj);
1325 if ((!ed) || (!part)) return;
1326 rp = _edje_real_part_recursive_get(ed, (char *)part);
1327 if (!rp) return;
1328 if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return;
1329 _edje_object_part_text_raw_append(obj, rp, part, text);
1330 rp->edje->dirty = 1;
1331#ifdef EDJE_CALC_CACHE
1332 rp->invalidate = 1;
1333#endif
1334 _edje_recalc(rp->edje);
1335 if (rp->edje->text_change.func)
1336 rp->edje->text_change.func(rp->edje->text_change.data, obj, part);
1337}
1338
1339EAPI const Eina_List *
1340edje_object_part_text_anchor_list_get(const Evas_Object *obj, const char *part)
1341{
1342 Edje *ed;
1343 Edje_Real_Part *rp;
1344
1345 ed = _edje_fetch(obj);
1346 if ((!ed) || (!part)) return NULL;
1347 rp = _edje_real_part_recursive_get(ed, (char *)part);
1348 if (!rp) return NULL;
1349 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1350 return _edje_entry_anchors_list(rp);
1351 return NULL;
1352}
1353
1354EAPI const Eina_List *
1355edje_object_part_text_anchor_geometry_get(const Evas_Object *obj, const char *part, const char *anchor)
1356{
1357 Edje *ed;
1358 Edje_Real_Part *rp;
1359
1360 ed = _edje_fetch(obj);
1361 if ((!ed) || (!part)) return NULL;
1362 rp = _edje_real_part_recursive_get(ed, (char *)part);
1363 if (!rp) return NULL;
1364 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1365 return _edje_entry_anchor_geometry_get(rp, anchor);
1366 return NULL;
1367}
1368
1369EAPI const Eina_List *
1370edje_object_part_text_item_list_get(const Evas_Object *obj, const char *part)
1371{
1372 Edje *ed;
1373 Edje_Real_Part *rp;
1374
1375 ed = _edje_fetch(obj);
1376 if ((!ed) || (!part)) return NULL;
1377 rp = _edje_real_part_recursive_get(ed, (char *)part);
1378 if (!rp) return NULL;
1379 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1380 return _edje_entry_items_list(rp);
1381 return NULL;
1382}
1383
1384EAPI Eina_Bool
1385edje_object_part_text_item_geometry_get(const Evas_Object *obj, const char *part, const char *item, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
1386{
1387 Edje *ed;
1388 Edje_Real_Part *rp;
1389
1390 ed = _edje_fetch(obj);
1391 if ((!ed) || (!part)) return EINA_FALSE;
1392 rp = _edje_real_part_recursive_get(ed, (char *)part);
1393 if (!rp) return EINA_FALSE;
1394 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1395 return _edje_entry_item_geometry_get(rp, item, cx, cy, cw, ch);
1396 return EINA_FALSE;
1397}
1398
1399EAPI void
1400edje_object_part_text_cursor_geometry_get(const Evas_Object *obj, const char *part, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
1401{
1402 Edje *ed;
1403 Edje_Real_Part *rp;
1404
1405 ed = _edje_fetch(obj);
1406 if (x) *x = 0;
1407 if (y) *y = 0;
1408 if (w) *w = 0;
1409 if (h) *h = 0;
1410 if ((!ed) || (!part)) return;
1411 rp = _edje_real_part_recursive_get(ed, (char *)part);
1412 if (!rp) return;
1413 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1414 {
1415 _edje_entry_cursor_geometry_get(rp, x, y, w, h);
1416 if (x) *x -= rp->edje->x;
1417 if (y) *y -= rp->edje->y;
1418 }
1419 return;
1420}
1421
1422EAPI void
1423edje_object_part_text_select_allow_set(const Evas_Object *obj, const char *part, Eina_Bool allow)
1424{
1425 Edje *ed;
1426 Edje_Real_Part *rp;
1427
1428 ed = _edje_fetch(obj);
1429 if ((!ed) || (!part)) return;
1430 rp = _edje_real_part_recursive_get(ed, (char *)part);
1431 if (!rp) return;
1432 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1433 _edje_entry_select_allow_set(rp, allow);
1434}
1435
1436EAPI void
1437edje_object_part_text_select_abort(const Evas_Object *obj, const char *part)
1438{
1439 Edje *ed;
1440 Edje_Real_Part *rp;
1441
1442 ed = _edje_fetch(obj);
1443 if ((!ed) || (!part)) return;
1444 rp = _edje_real_part_recursive_get(ed, (char *)part);
1445 if (!rp) return;
1446 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1447 _edje_entry_select_abort(rp);
1448}
1449
1450EAPI void
1451edje_object_part_text_select_begin(const Evas_Object *obj, const char *part)
1452{
1453 Edje *ed;
1454 Edje_Real_Part *rp;
1455
1456 ed = _edje_fetch(obj);
1457 if ((!ed) || (!part)) return;
1458 rp = _edje_real_part_recursive_get(ed, (char *)part);
1459 if (!rp) return;
1460 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1461 _edje_entry_select_begin(rp);
1462}
1463
1464EAPI void
1465edje_object_part_text_select_extend(const Evas_Object *obj, const char *part)
1466{
1467 Edje *ed;
1468 Edje_Real_Part *rp;
1469
1470 ed = _edje_fetch(obj);
1471 if ((!ed) || (!part)) return;
1472 rp = _edje_real_part_recursive_get(ed, (char *)part);
1473 if (!rp) return;
1474 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1475 _edje_entry_select_extend(rp);
1476}
1477
1478EAPI Eina_Bool
1479edje_object_part_text_cursor_next(Evas_Object *obj, const char *part, Edje_Cursor cur)
1480{
1481 Edje *ed;
1482 Edje_Real_Part *rp;
1483
1484 ed = _edje_fetch(obj);
1485 if ((!ed) || (!part)) return EINA_FALSE;
1486 rp = _edje_real_part_recursive_get(ed, (char *)part);
1487 if (!rp) return EINA_FALSE;
1488 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1489 {
1490 return _edje_entry_cursor_next(rp, cur);
1491 }
1492 return EINA_FALSE;
1493}
1494
1495EAPI Eina_Bool
1496edje_object_part_text_cursor_prev(Evas_Object *obj, const char *part, Edje_Cursor cur)
1497{
1498 Edje *ed;
1499 Edje_Real_Part *rp;
1500
1501 ed = _edje_fetch(obj);
1502 if ((!ed) || (!part)) return EINA_FALSE;
1503 rp = _edje_real_part_recursive_get(ed, (char *)part);
1504 if (!rp) return EINA_FALSE;
1505 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1506 {
1507 return _edje_entry_cursor_prev(rp, cur);
1508 }
1509 return EINA_FALSE;
1510}
1511
1512EAPI Eina_Bool
1513edje_object_part_text_cursor_up(Evas_Object *obj, const char *part, Edje_Cursor cur)
1514{
1515 Edje *ed;
1516 Edje_Real_Part *rp;
1517
1518 ed = _edje_fetch(obj);
1519 if ((!ed) || (!part)) return EINA_FALSE;
1520 rp = _edje_real_part_recursive_get(ed, (char *)part);
1521 if (!rp) return EINA_FALSE;
1522 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1523 {
1524 return _edje_entry_cursor_up(rp, cur);
1525 }
1526 return EINA_FALSE;
1527}
1528
1529EAPI Eina_Bool
1530edje_object_part_text_cursor_down(Evas_Object *obj, const char *part, Edje_Cursor cur)
1531{
1532 Edje *ed;
1533 Edje_Real_Part *rp;
1534
1535 ed = _edje_fetch(obj);
1536 if ((!ed) || (!part)) return EINA_FALSE;
1537 rp = _edje_real_part_recursive_get(ed, (char *)part);
1538 if (!rp) return EINA_FALSE;
1539 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1540 {
1541 return _edje_entry_cursor_down(rp, cur);
1542 }
1543 return EINA_FALSE;
1544}
1545
1546EAPI void
1547edje_object_part_text_cursor_begin_set(Evas_Object *obj, const char *part, Edje_Cursor cur)
1548{
1549 Edje *ed;
1550 Edje_Real_Part *rp;
1551
1552 ed = _edje_fetch(obj);
1553 if ((!ed) || (!part)) return;
1554 rp = _edje_real_part_recursive_get(ed, (char *)part);
1555 if (!rp) return;
1556 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1557 {
1558 _edje_entry_cursor_begin(rp, cur);
1559 }
1560}
1561
1562EAPI void
1563edje_object_part_text_cursor_end_set(Evas_Object *obj, const char *part, Edje_Cursor cur)
1564{
1565 Edje *ed;
1566 Edje_Real_Part *rp;
1567
1568 ed = _edje_fetch(obj);
1569 if ((!ed) || (!part)) return;
1570 rp = _edje_real_part_recursive_get(ed, (char *)part);
1571 if (!rp) return;
1572 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1573 {
1574 _edje_entry_cursor_end(rp, cur);
1575 }
1576}
1577
1578EAPI void
1579edje_object_part_text_cursor_copy(Evas_Object *obj, const char *part, Edje_Cursor src, Edje_Cursor dst)
1580{
1581 Edje *ed;
1582 Edje_Real_Part *rp;
1583
1584 ed = _edje_fetch(obj);
1585 if ((!ed) || (!part)) return;
1586 rp = _edje_real_part_recursive_get(ed, (char *)part);
1587 if (!rp) return;
1588 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1589 {
1590 _edje_entry_cursor_copy(rp, src, dst);
1591 }
1592}
1593
1594EAPI void
1595edje_object_part_text_cursor_line_begin_set(Evas_Object *obj, const char *part, Edje_Cursor cur)
1596{
1597 Edje *ed;
1598 Edje_Real_Part *rp;
1599
1600 ed = _edje_fetch(obj);
1601 if ((!ed) || (!part)) return;
1602 rp = _edje_real_part_recursive_get(ed, (char *)part);
1603 if (!rp) return;
1604 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1605 {
1606 _edje_entry_cursor_line_begin(rp, cur);
1607 }
1608}
1609
1610EAPI void
1611edje_object_part_text_cursor_line_end_set(Evas_Object *obj, const char *part, Edje_Cursor cur)
1612{
1613 Edje *ed;
1614 Edje_Real_Part *rp;
1615
1616 ed = _edje_fetch(obj);
1617 if ((!ed) || (!part)) return;
1618 rp = _edje_real_part_recursive_get(ed, (char *)part);
1619 if (!rp) return;
1620 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1621 {
1622 _edje_entry_cursor_line_end(rp, cur);
1623 }
1624}
1625
1626EAPI Eina_Bool
1627edje_object_part_text_cursor_coord_set(Evas_Object *obj, const char *part,
1628 Edje_Cursor cur, Evas_Coord x, Evas_Coord y)
1629{
1630 Edje *ed;
1631 Edje_Real_Part *rp;
1632
1633 ed = _edje_fetch(obj);
1634 if ((!ed) || (!part)) return EINA_FALSE;
1635 rp = _edje_real_part_recursive_get(ed, (char *)part);
1636 if (!rp) return EINA_FALSE;
1637 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1638 {
1639 return _edje_entry_cursor_coord_set(rp, cur, x, y);
1640 }
1641 return EINA_FALSE;
1642}
1643
1644EAPI Eina_Bool
1645edje_object_part_text_cursor_is_format_get(const Evas_Object *obj, const char *part, Edje_Cursor cur)
1646{
1647 Edje *ed;
1648 Edje_Real_Part *rp;
1649
1650 ed = _edje_fetch(obj);
1651 if ((!ed) || (!part)) return EINA_FALSE;
1652 rp = _edje_real_part_recursive_get(ed, (char *)part);
1653 if (!rp) return EINA_FALSE;
1654 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1655 {
1656 return _edje_entry_cursor_is_format_get(rp, cur);
1657 }
1658 return EINA_FALSE;
1659}
1660
1661EAPI Eina_Bool
1662edje_object_part_text_cursor_is_visible_format_get(const Evas_Object *obj, const char *part, Edje_Cursor cur)
1663{
1664 Edje *ed;
1665 Edje_Real_Part *rp;
1666
1667 ed = _edje_fetch(obj);
1668 if ((!ed) || (!part)) return 0;
1669 rp = _edje_real_part_recursive_get(ed, (char *)part);
1670 if (!rp) return 0;
1671 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1672 {
1673 return _edje_entry_cursor_is_visible_format_get(rp, cur);
1674 }
1675 return 0;
1676}
1677
1678EAPI const char *
1679edje_object_part_text_cursor_content_get(const Evas_Object *obj, const char *part, Edje_Cursor cur)
1680{
1681 Edje *ed;
1682 Edje_Real_Part *rp;
1683
1684 ed = _edje_fetch(obj);
1685 if ((!ed) || (!part)) return NULL;
1686 rp = _edje_real_part_recursive_get(ed, part);
1687 if (!rp) return NULL;
1688 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1689 {
1690 return _edje_entry_cursor_content_get(rp, cur);
1691 }
1692 return NULL;
1693}
1694
1695EAPI void
1696edje_object_part_text_cursor_pos_set(Evas_Object *obj, const char *part, Edje_Cursor cur, int pos)
1697{
1698 Edje *ed;
1699 Edje_Real_Part *rp;
1700
1701 ed = _edje_fetch(obj);
1702 if ((!ed) || (!part)) return;
1703 rp = _edje_real_part_recursive_get(ed, part);
1704 if (!rp) return;
1705 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1706 {
1707 _edje_entry_cursor_pos_set(rp, cur, pos);
1708 }
1709}
1710
1711EAPI int
1712edje_object_part_text_cursor_pos_get(const Evas_Object *obj, const char *part, Edje_Cursor cur)
1713{
1714 Edje *ed;
1715 Edje_Real_Part *rp;
1716
1717 ed = _edje_fetch(obj);
1718 if ((!ed) || (!part)) return 0;
1719 rp = _edje_real_part_recursive_get(ed, part);
1720 if (!rp) return 0;
1721 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1722 {
1723 return _edje_entry_cursor_pos_get(rp, cur);
1724 }
1725 return 0;
1726}
1727
1728EAPI void
1729edje_object_part_text_input_panel_layout_set(const Evas_Object *obj, const char *part, Edje_Input_Panel_Layout layout)
1730{
1731 Edje *ed;
1732 Edje_Real_Part *rp;
1733
1734 ed = _edje_fetch(obj);
1735 if ((!ed) || (!part)) return;
1736 rp = _edje_real_part_recursive_get(ed, part);
1737 if (!rp) return;
1738 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1739 {
1740 return _edje_entry_input_panel_layout_set(rp, layout);
1741 }
1742}
1743
1744EAPI Edje_Input_Panel_Layout
1745edje_object_part_text_input_panel_layout_get(const Evas_Object *obj, const char *part)
1746{
1747 Edje *ed;
1748 Edje_Real_Part *rp;
1749
1750 ed = _edje_fetch(obj);
1751 if ((!ed) || (!part)) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
1752 rp = _edje_real_part_recursive_get(ed, part);
1753 if (!rp) return EINA_FALSE;
1754 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1755 {
1756 return _edje_entry_input_panel_layout_get(rp);
1757 }
1758 return EDJE_INPUT_PANEL_LAYOUT_INVALID;
1759}
1760
1761EAPI void
1762edje_object_part_text_autocapital_type_set(const Evas_Object *obj, const char *part, Edje_Text_Autocapital_Type autocapital_type)
1763{
1764 Edje *ed;
1765 Edje_Real_Part *rp;
1766
1767 ed = _edje_fetch(obj);
1768 if ((!ed) || (!part)) return;
1769 rp = _edje_real_part_recursive_get(ed, (char *)part);
1770 if (!rp) return;
1771 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1772 {
1773 _edje_entry_autocapital_type_set(rp, autocapital_type);
1774 }
1775}
1776
1777EAPI Edje_Text_Autocapital_Type
1778edje_object_part_text_autocapital_type_get(const Evas_Object *obj, const char *part)
1779{
1780 Edje *ed;
1781 Edje_Real_Part *rp;
1782
1783 ed = _edje_fetch(obj);
1784 if ((!ed) || (!part)) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
1785 rp = _edje_real_part_recursive_get(ed, (char *)part);
1786 if (!rp) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
1787 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1788 {
1789 return _edje_entry_autocapital_type_get(rp);
1790 }
1791 return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
1792}
1793
1794EAPI void
1795edje_object_part_text_input_panel_enabled_set(const Evas_Object *obj, const char *part, Eina_Bool enabled)
1796{
1797 Edje *ed;
1798 Edje_Real_Part *rp;
1799
1800 ed = _edje_fetch(obj);
1801 if ((!ed) || (!part)) return;
1802 rp = _edje_real_part_recursive_get(ed, part);
1803 if (!rp) return;
1804 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1805 {
1806 return _edje_entry_input_panel_enabled_set(rp, enabled);
1807 }
1808}
1809
1810EAPI Eina_Bool
1811edje_object_part_text_input_panel_enabled_get(const Evas_Object *obj, const char *part)
1812{
1813 Edje *ed;
1814 Edje_Real_Part *rp;
1815
1816 ed = _edje_fetch(obj);
1817 if ((!ed) || (!part)) return EINA_FALSE;
1818 rp = _edje_real_part_recursive_get(ed, part);
1819 if (!rp) return EINA_FALSE;
1820 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1821 {
1822 return _edje_entry_input_panel_enabled_get(rp);
1823 }
1824 return EINA_FALSE;
1825}
1826
1827EAPI void
1828edje_object_text_insert_filter_callback_add(Evas_Object *obj, const char *part, Edje_Text_Filter_Cb func, void *data)
1829{
1830 Edje *ed;
1831 Edje_Text_Insert_Filter_Callback *cb;
1832
1833 ed = _edje_fetch(obj);
1834 if ((!ed) || (!part)) return;
1835 cb = calloc(1, sizeof(Edje_Text_Insert_Filter_Callback));
1836 cb->part = eina_stringshare_add(part);
1837 cb->func = func;
1838 cb->data = (void *)data;
1839 ed->text_insert_filter_callbacks =
1840 eina_list_append(ed->text_insert_filter_callbacks, cb);
1841}
1842
1843EAPI void *
1844edje_object_text_insert_filter_callback_del(Evas_Object *obj, const char *part, Edje_Text_Filter_Cb func)
1845{
1846 Edje *ed;
1847 Edje_Text_Insert_Filter_Callback *cb;
1848 Eina_List *l;
1849
1850 ed = _edje_fetch(obj);
1851 if ((!ed) || (!part)) return NULL;
1852 EINA_LIST_FOREACH(ed->text_insert_filter_callbacks, l, cb)
1853 {
1854 if ((!strcmp(cb->part, part)) && (cb->func == func))
1855 {
1856 void *data = cb->data;
1857 ed->text_insert_filter_callbacks =
1858 eina_list_remove_list(ed->text_insert_filter_callbacks, l);
1859 eina_stringshare_del(cb->part);
1860 free(cb);
1861 return data;
1862 }
1863 }
1864 return NULL;
1865}
1866
1867EAPI void *
1868edje_object_text_insert_filter_callback_del_full(Evas_Object *obj, const char *part, Edje_Text_Filter_Cb func, void *data)
1869{
1870 Edje *ed;
1871 Edje_Text_Insert_Filter_Callback *cb;
1872 Eina_List *l;
1873
1874 ed = _edje_fetch(obj);
1875 if ((!ed) || (!part)) return NULL;
1876 EINA_LIST_FOREACH(ed->text_insert_filter_callbacks, l, cb)
1877 {
1878 if ((!strcmp(cb->part, part)) && (cb->func == func) &&
1879 (cb->data == data))
1880 {
1881 void *tmp = cb->data;
1882 ed->text_insert_filter_callbacks =
1883 eina_list_remove_list(ed->text_insert_filter_callbacks, l);
1884 eina_stringshare_del(cb->part);
1885 free(cb);
1886 return tmp;
1887 }
1888 }
1889 return NULL;
1890}
1891
1892EAPI Eina_Bool
1893edje_object_part_swallow(Evas_Object *obj, const char *part, Evas_Object *obj_swallow)
1894{
1895 Edje *ed;
1896 Edje_Real_Part *rp;
1897
1898 ed = _edje_fetch(obj);
1899 if ((!ed) || (!part)) return EINA_FALSE;
1900
1901 /* Need to recalc before providing the object. */
1902 // XXX: I guess this is not required, removing for testing purposes
1903 // XXX: uncomment if you see glitches in e17 or others.
1904 // XXX: by Gustavo, January 21th 2009.
1905 // XXX: I got a backtrace with over 30000 calls without this,
1906 // XXX: only with 32px shelves. The problem is probably somewhere else,
1907 // XXX: but until it's found, leave this here.
1908 // XXX: by Sachiel, January 21th 2009, 19:30 UTC
1909 _edje_recalc_do(ed);
1910
1911 rp = _edje_real_part_recursive_get(ed, (char *)part);
1912 if (!rp) return EINA_FALSE;
1913 if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
1914 {
1915 ERR("cannot swallow part %s: not swallow type!", rp->part->name);
1916 return EINA_FALSE;
1917 }
1918 _edje_real_part_swallow(rp, obj_swallow, EINA_TRUE);
1919 return EINA_TRUE;
1920}
1921
1922static void
1923_recalc_extern_parent(Evas_Object *obj)
1924{
1925 Evas_Object *parent;
1926 Edje *ed;
1927
1928 parent = evas_object_smart_parent_get(obj);
1929 ed = _edje_fetch(parent);
1930
1931 ed->dirty = 1;
1932 _edje_recalc(ed);
1933}
1934
1935EAPI void
1936edje_extern_object_min_size_set(Evas_Object *obj, Evas_Coord minw, Evas_Coord minh)
1937{
1938 Edje_Real_Part *rp;
1939
1940 evas_object_size_hint_min_set(obj, minw, minh);
1941 rp = evas_object_data_get(obj, "\377 edje.swallowing_part");
1942 if (rp)
1943 {
1944 rp->swallow_params.min.w = minw;
1945 rp->swallow_params.min.h = minh;
1946
1947 _recalc_extern_parent(obj);
1948 }
1949}
1950
1951EAPI void
1952edje_extern_object_max_size_set(Evas_Object *obj, Evas_Coord maxw, Evas_Coord maxh)
1953{
1954 Edje_Real_Part *rp;
1955
1956 evas_object_size_hint_max_set(obj, maxw, maxh);
1957 rp = evas_object_data_get(obj, "\377 edje.swallowing_part");
1958 if (rp)
1959 {
1960 rp->swallow_params.max.w = maxw;
1961 rp->swallow_params.max.h = maxh;
1962
1963 _recalc_extern_parent(obj);
1964 }
1965}
1966
1967EAPI void
1968edje_extern_object_aspect_set(Evas_Object *obj, Edje_Aspect_Control aspect, Evas_Coord aw, Evas_Coord ah)
1969{
1970 Edje_Real_Part *rp;
1971 Evas_Aspect_Control asp;
1972
1973 asp = EVAS_ASPECT_CONTROL_NONE;
1974 switch (aspect)
1975 {
1976 case EDJE_ASPECT_CONTROL_NONE: asp = EVAS_ASPECT_CONTROL_NONE; break;
1977 case EDJE_ASPECT_CONTROL_NEITHER: asp = EVAS_ASPECT_CONTROL_NEITHER; break;
1978 case EDJE_ASPECT_CONTROL_HORIZONTAL: asp = EVAS_ASPECT_CONTROL_HORIZONTAL; break;
1979 case EDJE_ASPECT_CONTROL_VERTICAL: asp = EVAS_ASPECT_CONTROL_VERTICAL; break;
1980 case EDJE_ASPECT_CONTROL_BOTH: asp = EVAS_ASPECT_CONTROL_BOTH; break;
1981 default: break;
1982 }
1983 if (aw < 1) aw = 1;
1984 if (ah < 1) ah = 1;
1985 evas_object_size_hint_aspect_set(obj, asp, aw, ah);
1986 rp = evas_object_data_get(obj, "\377 edje.swallowing_part");
1987 if (rp)
1988 {
1989 rp->swallow_params.aspect.mode = aspect;
1990 rp->swallow_params.aspect.w = aw;
1991 rp->swallow_params.aspect.h = ah;
1992 _recalc_extern_parent(obj);
1993 }
1994}
1995
1996struct edje_box_layout_builtin {
1997 const char *name;
1998 Evas_Object_Box_Layout cb;
1999};
2000
2001static Evas_Object_Box_Layout
2002_edje_box_layout_builtin_find(const char *name)
2003{
2004 const struct edje_box_layout_builtin _edje_box_layout_builtin[] = {
2005 {"horizontal", evas_object_box_layout_horizontal},
2006 {"horizontal_flow", evas_object_box_layout_flow_horizontal},
2007 {"horizontal_homogeneous", evas_object_box_layout_homogeneous_horizontal},
2008 {"horizontal_max", evas_object_box_layout_homogeneous_max_size_horizontal},
2009 {"stack", evas_object_box_layout_stack},
2010 {"vertical", evas_object_box_layout_vertical},
2011 {"vertical_flow", evas_object_box_layout_flow_vertical},
2012 {"vertical_homogeneous", evas_object_box_layout_homogeneous_vertical},
2013 {"vertical_max", evas_object_box_layout_homogeneous_max_size_vertical},
2014 {NULL, NULL}
2015 };
2016 const struct edje_box_layout_builtin *base;
2017
2018 switch (name[0])
2019 {
2020 case 'h':
2021 base = _edje_box_layout_builtin + 0;
2022 break;
2023 case 's':
2024 base = _edje_box_layout_builtin + 4;
2025 break;
2026 case 'v':
2027 base = _edje_box_layout_builtin + 5;
2028 break;
2029 default:
2030 return NULL;
2031 }
2032
2033 for (; (base->name) && (base->name[0] == name[0]); base++)
2034 if (strcmp(base->name, name) == 0)
2035 return base->cb;
2036
2037 return NULL;
2038}
2039
2040static Eina_Rbtree_Direction
2041_edje_box_layout_external_node_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, __UNUSED__ void *data)
2042{
2043 Edje_Box_Layout *l = (Edje_Box_Layout *)left;
2044 Edje_Box_Layout *r = (Edje_Box_Layout *)right;
2045
2046 if (strcmp(l->name, r->name) < 0)
2047 return EINA_RBTREE_RIGHT;
2048 else
2049 return EINA_RBTREE_LEFT;
2050}
2051
2052static int
2053_edje_box_layout_external_find_cmp(const Eina_Rbtree *node, const void *key, __UNUSED__ int length, __UNUSED__ void *data)
2054{
2055 Edje_Box_Layout *l = (Edje_Box_Layout *)node;
2056 return strcmp(key, l->name);
2057}
2058
2059static Edje_Box_Layout *
2060_edje_box_layout_external_find(const char *name)
2061{
2062 return (Edje_Box_Layout *)eina_rbtree_inline_lookup
2063 (_edje_box_layout_registry, name, 0, _edje_box_layout_external_find_cmp,
2064 NULL);
2065}
2066
2067Eina_Bool
2068_edje_box_layout_find(const char *name, Evas_Object_Box_Layout *cb, void **data, void (**free_data)(void *data))
2069{
2070 const Edje_Box_Layout *l;
2071
2072 if (!name) return EINA_FALSE;
2073
2074 *cb = _edje_box_layout_builtin_find(name);
2075 if (*cb)
2076 {
2077 *free_data = NULL;
2078 *data = NULL;
2079 return EINA_TRUE;
2080 }
2081
2082 l = _edje_box_layout_external_find(name);
2083 if (!l) return EINA_FALSE;
2084
2085 *cb = l->func;
2086 *free_data = l->layout_data_free;
2087 if (l->layout_data_get)
2088 *data = l->layout_data_get(l->data);
2089 else
2090 *data = NULL;
2091
2092 return EINA_TRUE;
2093}
2094
2095static void
2096_edje_box_layout_external_free(Eina_Rbtree *node, __UNUSED__ void *data)
2097{
2098 Edje_Box_Layout *l = (Edje_Box_Layout *)node;
2099
2100 if (l->data && l->free_data)
2101 l->free_data(l->data);
2102 free(l);
2103}
2104
2105static Edje_Box_Layout *
2106_edje_box_layout_external_new(const char *name, Evas_Object_Box_Layout func, void *(*layout_data_get)(void *), void (*layout_data_free)(void *), void (*free_data)(void *), void *data)
2107{
2108 Edje_Box_Layout *l;
2109 size_t name_len;
2110
2111 name_len = strlen(name) + 1;
2112 l = malloc(sizeof(Edje_Box_Layout) + name_len);
2113 if (!l)
2114 {
2115 perror("malloc");
2116 return NULL;
2117 }
2118
2119 l->func = func;
2120 l->layout_data_get = layout_data_get;
2121 l->layout_data_free = layout_data_free;
2122 l->free_data = free_data;
2123 l->data = data;
2124
2125 memcpy(l->name, name, name_len);
2126
2127 return l;
2128}
2129
2130EAPI void
2131edje_box_layout_register(const char *name, Evas_Object_Box_Layout func, void *(*layout_data_get)(void *), void (*layout_data_free)(void *), void (*free_data)(void *), void *data)
2132{
2133 Edje_Box_Layout *l;
2134
2135 if (!name) return;
2136
2137 if (_edje_box_layout_builtin_find(name))
2138 {
2139 ERR("Cannot register layout '%s': would override builtin!",
2140 name);
2141
2142 if (data && free_data) free_data(data);
2143 return;
2144 }
2145
2146 l = _edje_box_layout_external_find(name);
2147 if (!l)
2148 {
2149 if (!func)
2150 {
2151 if (data && free_data) free_data(data);
2152 return;
2153 }
2154
2155 l = _edje_box_layout_external_new
2156 (name, func, layout_data_get, layout_data_free, free_data, data);
2157 if (!l)
2158 return;
2159
2160 _edje_box_layout_registry = eina_rbtree_inline_insert
2161 (_edje_box_layout_registry, (Eina_Rbtree *)l,
2162 _edje_box_layout_external_node_cmp, NULL);
2163 }
2164 else
2165 {
2166 if (func)
2167 {
2168 if (l->data && l->free_data) l->free_data(l->data);
2169
2170 l->func = func;
2171 l->layout_data_get = layout_data_get;
2172 l->layout_data_free = layout_data_free;
2173 l->free_data = free_data;
2174 l->data = data;
2175 }
2176 else
2177 {
2178 if (data && free_data) free_data(data);
2179
2180 _edje_box_layout_registry = eina_rbtree_inline_remove
2181 (_edje_box_layout_registry, (Eina_Rbtree *)l,
2182 _edje_box_layout_external_node_cmp, NULL);
2183 _edje_box_layout_external_free((Eina_Rbtree *)l, NULL);
2184 }
2185 }
2186}
2187
2188EAPI void
2189edje_object_part_unswallow(Evas_Object *obj __UNUSED__, Evas_Object *obj_swallow)
2190{
2191 Edje_Real_Part *rp;
2192
2193 if (!obj_swallow) return;
2194
2195 rp = (Edje_Real_Part *)evas_object_data_get(obj_swallow, "\377 edje.swallowing_part");
2196 if (!rp)
2197 return;
2198 if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
2199 {
2200 ERR("cannot unswallow part %s: not swallow type!", rp->part->name);
2201 return;
2202 }
2203 if (rp->swallowed_object == obj_swallow)
2204 {
2205 evas_object_smart_member_del(rp->swallowed_object);
2206 evas_object_event_callback_del_full(rp->swallowed_object,
2207 EVAS_CALLBACK_FREE,
2208 _edje_object_part_swallow_free_cb,
2209 rp->edje->obj);
2210 evas_object_event_callback_del_full(rp->swallowed_object,
2211 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2212 _edje_object_part_swallow_changed_hints_cb,
2213 rp);
2214 evas_object_clip_unset(rp->swallowed_object);
2215 evas_object_data_del(rp->swallowed_object, "\377 edje.swallowing_part");
2216
2217 if (rp->part->mouse_events)
2218 _edje_callbacks_del(rp->swallowed_object, rp->edje);
2219 _edje_callbacks_focus_del(rp->swallowed_object, rp->edje);
2220
2221 rp->swallowed_object = NULL;
2222 rp->swallow_params.min.w = 0;
2223 rp->swallow_params.min.h = 0;
2224 rp->swallow_params.max.w = 0;
2225 rp->swallow_params.max.h = 0;
2226 rp->edje->dirty = 1;
2227#ifdef EDJE_CALC_CACHE
2228 rp->invalidate = 1;
2229#endif
2230 _edje_recalc_do(rp->edje);
2231 return;
2232 }
2233}
2234
2235EAPI Evas_Object *
2236edje_object_part_swallow_get(const Evas_Object *obj, const char *part)
2237{
2238 Edje *ed;
2239 Edje_Real_Part *rp;
2240
2241 ed = _edje_fetch(obj);
2242 if ((!ed) || (!part)) return NULL;
2243
2244 /* Need to recalc before providing the object. */
2245 _edje_recalc_do(ed);
2246
2247 rp = _edje_real_part_recursive_get(ed, (char *)part);
2248 if (!rp) return NULL;
2249 return rp->swallowed_object;
2250}
2251
2252EAPI void
2253edje_object_size_min_get(const Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh)
2254{
2255 Edje *ed;
2256
2257 ed = _edje_fetch(obj);
2258 if ((!ed) || (!ed->collection))
2259 {
2260 if (minw) *minw = 0;
2261 if (minh) *minh = 0;
2262 return;
2263 }
2264 if (minw) *minw = ed->collection->prop.min.w;
2265 if (minh) *minh = ed->collection->prop.min.h;
2266}
2267
2268EAPI void
2269edje_object_size_max_get(const Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *maxh)
2270{
2271 Edje *ed;
2272
2273 ed = _edje_fetch(obj);
2274 if ((!ed) || (!ed->collection))
2275 {
2276 if (maxw) *maxw = 0;
2277 if (maxh) *maxh = 0;
2278 return;
2279 }
2280
2281 /* Need to recalc before providing the object. */
2282 _edje_recalc_do(ed);
2283
2284 if (ed->collection->prop.max.w == 0)
2285 {
2286 /* XXX TODO: convert maxw to 0, fix things that break. */
2287 if (maxw) *maxw = EDJE_INF_MAX_W;
2288 }
2289 else
2290 {
2291 if (maxw) *maxw = ed->collection->prop.max.w;
2292 }
2293 if (ed->collection->prop.max.h == 0)
2294 {
2295 /* XXX TODO: convert maxh to 0, fix things that break. */
2296 if (maxh) *maxh = EDJE_INF_MAX_H;
2297 }
2298 else
2299 {
2300 if (maxh) *maxh = ed->collection->prop.max.h;
2301 }
2302}
2303
2304EAPI void
2305edje_object_calc_force(Evas_Object *obj)
2306{
2307 Edje *ed;
2308 int pf, pf2;
2309
2310 ed = _edje_fetch(obj);
2311 if (!ed) return;
2312 ed->dirty = 1;
2313#ifdef EDJE_CALC_CACHE
2314 ed->all_part_change = 1;
2315#endif
2316
2317 pf2 = _edje_freeze_val;
2318 pf = ed->freeze;
2319
2320 _edje_freeze_val = 0;
2321 ed->freeze = 0;
2322
2323 _edje_recalc_do(ed);
2324
2325 ed->freeze = pf;
2326 _edje_freeze_val = pf2;
2327}
2328
2329EAPI void
2330edje_object_size_min_calc(Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh)
2331{
2332 edje_object_size_min_restricted_calc(obj, minw, minh, 0, 0);
2333}
2334
2335EAPI Eina_Bool
2336edje_object_parts_extends_calc(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
2337{
2338 Edje *ed;
2339 Evas_Coord x1 = INT_MAX, y1 = INT_MAX;
2340 Evas_Coord x2 = 0, y2 = 0;
2341 unsigned int i;
2342
2343 ed = _edje_fetch(obj);
2344 if (!ed)
2345 {
2346 if (x) *x = 0;
2347 if (y) *y = 0;
2348 if (w) *w = 0;
2349 if (h) *h = 0;
2350 return EINA_FALSE;
2351 }
2352
2353 ed->calc_only = 1;
2354
2355 /* Need to recalc before providing the object. */
2356 ed->dirty = 1;
2357 _edje_recalc_do(ed);
2358
2359 for (i = 0; i < ed->table_parts_size; i++)
2360 {
2361 Edje_Real_Part *rp;
2362 Evas_Coord rpx1, rpy1;
2363 Evas_Coord rpx2, rpy2;
2364
2365 rp = ed->table_parts[i];
2366
2367 rpx1 = rp->x;
2368 rpy1 = rp->y;
2369 rpx2 = rpx1 + rp->w;
2370 rpy2 = rpy1 + rp->h;
2371
2372 if (x1 > rpx1) x1 = rpx1;
2373 if (y1 > rpy1) y1 = rpy1;
2374 if (x2 < rpx2) x2 = rpx2;
2375 if (y2 < rpy2) y2 = rpy2;
2376 }
2377
2378 ed->calc_only = 0;
2379
2380 if (x) *x = x1;
2381 if (y) *y = y1;
2382 if (w) *w = x2 - x1;
2383 if (h) *h = y2 - y1;
2384
2385 return EINA_TRUE;
2386}
2387
2388EAPI void
2389edje_object_size_min_restricted_calc(Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord restrictedw, Evas_Coord restrictedh)
2390{
2391 Edje *ed;
2392 Evas_Coord pw, ph;
2393 int maxw, maxh;
2394 int okw, okh;
2395 int reset_maxwh;
2396 Edje_Real_Part *pep = NULL;
2397 Eina_Bool has_non_fixed_tb = EINA_FALSE;
2398
2399 ed = _edje_fetch(obj);
2400 if ((!ed) || (!ed->collection))
2401 {
2402 if (minw) *minw = restrictedw;
2403 if (minh) *minh = restrictedh;
2404 return;
2405 }
2406 reset_maxwh = 1;
2407 ed->calc_only = 1;
2408 pw = ed->w;
2409 ph = ed->h;
2410
2411 again:
2412 ed->w = restrictedw;
2413 ed->h = restrictedh;
2414
2415 maxw = 0;
2416 maxh = 0;
2417
2418 do
2419 {
2420 unsigned int i;
2421
2422 okw = okh = 0;
2423 ed->dirty = 1;
2424#ifdef EDJE_CALC_CACHE
2425 ed->all_part_change = 1;
2426#endif
2427 _edje_recalc_do(ed);
2428 if (reset_maxwh)
2429 {
2430 maxw = 0;
2431 maxh = 0;
2432 }
2433 pep = NULL;
2434 for (i = 0; i < ed->table_parts_size; i++)
2435 {
2436 Edje_Real_Part *ep;
2437 int w, h;
2438 int didw;
2439
2440 ep = ed->table_parts[i];
2441 w = ep->w - ep->req.w;
2442 h = ep->h - ep->req.h;
2443 didw = 0;
2444 if (ep->chosen_description)
2445 {
2446 if (!ep->chosen_description->fixed.w)
2447 {
2448 if ((ep->part->type == EDJE_PART_TYPE_TEXTBLOCK))
2449 {
2450 Evas_Coord tb_mw;
2451 evas_object_textblock_size_formatted_get(ep->object,
2452 &tb_mw, NULL);
2453 tb_mw -= ep->req.w;
2454 if (tb_mw > w)
2455 {
2456 w = tb_mw;
2457 }
2458 has_non_fixed_tb = EINA_TRUE;
2459 }
2460 if (w > maxw)
2461 {
2462 maxw = w;
2463 okw = 1;
2464 pep = ep;
2465 didw = 1;
2466 }
2467 }
2468 if (!ep->chosen_description->fixed.h)
2469 {
2470 if (!((ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
2471 (!((Edje_Part_Description_Text *)ep->chosen_description)->text.min_x) &&
2472 (didw)))
2473 {
2474 if (h > maxh)
2475 {
2476 maxh = h;
2477 okh = 1;
2478 pep = ep;
2479 }
2480 }
2481
2482 if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
2483 {
2484 has_non_fixed_tb = EINA_TRUE;
2485 }
2486 }
2487 }
2488 }
2489 if (okw)
2490 {
2491 ed->w += maxw;
2492 if (ed->w < restrictedw) ed->w = restrictedw;
2493 }
2494 if (okh)
2495 {
2496 ed->h += maxh;
2497 if (ed->h < restrictedh) ed->h = restrictedh;
2498 }
2499 if ((ed->w > 4000) || (ed->h > 4000))
2500 {
2501 /* Only print it if we have a non-fixed textblock.
2502 * We should possibly avoid all of this if in this case, but in
2503 * the meanwhile, just doing this. */
2504 if (!has_non_fixed_tb)
2505 {
2506 if (pep)
2507 ERR("file %s, group %s has a non-fixed part '%s'. Adding 'fixed: 1 1;' to source EDC may help. Continuing discarding faulty part.",
2508 ed->path, ed->group, pep->part->name);
2509 else
2510 ERR("file %s, group %s overflowed 4000x4000 with minimum size of %dx%d. Continuing discarding faulty parts.",
2511 ed->path, ed->group, ed->w, ed->h);
2512 }
2513
2514 if (reset_maxwh)
2515 {
2516 reset_maxwh = 0;
2517 goto again;
2518 }
2519 }
2520 }
2521 while (okw || okh);
2522 ed->min.w = ed->w;
2523 ed->min.h = ed->h;
2524
2525 if (minw) *minw = ed->min.w;
2526 if (minh) *minh = ed->min.h;
2527
2528 ed->w = pw;
2529 ed->h = ph;
2530 ed->dirty = 1;
2531#ifdef EDJE_CALC_CACHE
2532 ed->all_part_change = 1;
2533#endif
2534 _edje_recalc(ed);
2535 ed->calc_only = 0;
2536}
2537
2538/* FIXME: Correctly return other states */
2539EAPI const char *
2540edje_object_part_state_get(const Evas_Object *obj, const char *part, double *val_ret)
2541{
2542 Edje *ed;
2543 Edje_Real_Part *rp;
2544
2545 ed = _edje_fetch(obj);
2546 if ((!ed) || (!part))
2547 {
2548 if (val_ret) *val_ret = 0;
2549 return "";
2550 }
2551
2552 /* Need to recalc before providing the object. */
2553 _edje_recalc_do(ed);
2554
2555 rp = _edje_real_part_recursive_get(ed, (char *)part);
2556 if (!rp)
2557 {
2558 if (val_ret) *val_ret = 0;
2559 INF("part not found");
2560 return "";
2561 }
2562 if (rp->chosen_description)
2563 {
2564 if (val_ret) *val_ret = rp->chosen_description->state.value;
2565 if (rp->chosen_description->state.name)
2566 return rp->chosen_description->state.name;
2567 return "default";
2568 }
2569 else
2570 {
2571 if (rp->param1.description)
2572 {
2573 if (val_ret) *val_ret = rp->param1.description->state.value;
2574 if (rp->param1.description->state.name)
2575 return rp->param1.description->state.name;
2576 return "default";
2577 }
2578 }
2579 if (val_ret) *val_ret = 0;
2580 return "";
2581}
2582
2583EAPI Edje_Drag_Dir
2584edje_object_part_drag_dir_get(const Evas_Object *obj, const char *part)
2585{
2586 Edje *ed;
2587 Edje_Real_Part *rp;
2588
2589 ed = _edje_fetch(obj);
2590 if ((!ed) || (!part)) return EDJE_DRAG_DIR_NONE;
2591
2592 /* Need to recalc before providing the object. */
2593 _edje_recalc_do(ed);
2594
2595 rp = _edje_real_part_recursive_get(ed, (char *)part);
2596 if (!rp) return EDJE_DRAG_DIR_NONE;
2597 if ((rp->part->dragable.x) && (rp->part->dragable.y)) return EDJE_DRAG_DIR_XY;
2598 else if (rp->part->dragable.x) return EDJE_DRAG_DIR_X;
2599 else if (rp->part->dragable.y) return EDJE_DRAG_DIR_Y;
2600 return EDJE_DRAG_DIR_NONE;
2601}
2602
2603EAPI Eina_Bool
2604edje_object_part_drag_value_set(Evas_Object *obj, const char *part, double dx, double dy)
2605{
2606 Edje *ed;
2607 Edje_Real_Part *rp;
2608
2609 ed = _edje_fetch(obj);
2610 if ((!ed) || (!part)) return EINA_FALSE;
2611 rp = _edje_real_part_recursive_get(ed, (char *)part);
2612 if (!rp) return EINA_FALSE;
2613 if (!rp->drag) return EINA_FALSE;
2614 if (rp->drag->down.count > 0) return EINA_FALSE;
2615 if (rp->part->dragable.confine_id != -1)
2616 {
2617 dx = CLAMP(dx, 0.0, 1.0);
2618 dy = CLAMP(dy, 0.0, 1.0);
2619 }
2620 if (rp->part->dragable.x < 0) dx = 1.0 - dx;
2621 if (rp->part->dragable.y < 0) dy = 1.0 - dy;
2622 if ((rp->drag->val.x == FROM_DOUBLE(dx)) && (rp->drag->val.y == FROM_DOUBLE(dy))) return EINA_TRUE;
2623 rp->drag->val.x = FROM_DOUBLE(dx);
2624 rp->drag->val.y = FROM_DOUBLE(dy);
2625#ifdef EDJE_CALC_CACHE
2626 rp->invalidate = 1;
2627#endif
2628 _edje_dragable_pos_set(rp->edje, rp, rp->drag->val.x, rp->drag->val.y);
2629 _edje_emit(rp->edje, "drag,set", rp->part->name);
2630 return EINA_TRUE;
2631}
2632
2633/* FIXME: Should this be x and y instead of dx/dy? */
2634EAPI Eina_Bool
2635edje_object_part_drag_value_get(const Evas_Object *obj, const char *part, double *dx, double *dy)
2636{
2637 Edje *ed;
2638 Edje_Real_Part *rp;
2639 double ddx, ddy;
2640
2641 ed = _edje_fetch(obj);
2642 if ((!ed) || (!part))
2643 {
2644 if (dx) *dx = 0;
2645 if (dy) *dy = 0;
2646 return EINA_FALSE;
2647 }
2648
2649 /* Need to recalc before providing the object. */
2650 _edje_recalc_do(ed);
2651
2652 rp = _edje_real_part_recursive_get(ed, (char *)part);
2653 if (!rp || !rp->drag)
2654 {
2655 if (dx) *dx = 0;
2656 if (dy) *dy = 0;
2657 return EINA_FALSE;
2658 }
2659 ddx = TO_DOUBLE(rp->drag->val.x);
2660 ddy = TO_DOUBLE(rp->drag->val.y);
2661 if (rp->part->dragable.x < 0) ddx = 1.0 - ddx;
2662 if (rp->part->dragable.y < 0) ddy = 1.0 - ddy;
2663 if (dx) *dx = ddx;
2664 if (dy) *dy = ddy;
2665 return EINA_TRUE;
2666}
2667
2668EAPI Eina_Bool
2669edje_object_part_drag_size_set(Evas_Object *obj, const char *part, double dw, double dh)
2670{
2671 Edje *ed;
2672 Edje_Real_Part *rp;
2673
2674 ed = _edje_fetch(obj);
2675 if ((!ed) || (!part)) return EINA_FALSE;
2676 rp = _edje_real_part_recursive_get(ed, (char *)part);
2677 if (!rp) return EINA_FALSE;
2678 if (!rp->drag) return EINA_FALSE;
2679 if (dw < 0.0) dw = 0.0;
2680 else if (dw > 1.0) dw = 1.0;
2681 if (dh < 0.0) dh = 0.0;
2682 else if (dh > 1.0) dh = 1.0;
2683 if ((rp->drag->size.x == FROM_DOUBLE(dw)) && (rp->drag->size.y == FROM_DOUBLE(dh))) return EINA_TRUE;
2684 rp->drag->size.x = FROM_DOUBLE(dw);
2685 rp->drag->size.y = FROM_DOUBLE(dh);
2686 rp->edje->dirty = 1;
2687#ifdef EDJE_CALC_CACHE
2688 rp->invalidate = 1;
2689#endif
2690 _edje_recalc(rp->edje);
2691 return EINA_TRUE;
2692}
2693
2694EAPI Eina_Bool
2695edje_object_part_drag_size_get(const Evas_Object *obj, const char *part, double *dw, double *dh)
2696{
2697 Edje *ed;
2698 Edje_Real_Part *rp;
2699
2700 ed = _edje_fetch(obj);
2701 if ((!ed) || (!part))
2702 {
2703 if (dw) *dw = 0;
2704 if (dh) *dh = 0;
2705 return EINA_FALSE;
2706 }
2707
2708 /* Need to recalc before providing the object. */
2709 _edje_recalc_do(ed);
2710
2711 rp = _edje_real_part_recursive_get(ed, (char *)part);
2712 if (!rp || !rp->drag)
2713 {
2714 if (dw) *dw = 0;
2715 if (dh) *dh = 0;
2716 return EINA_FALSE;
2717 }
2718 if (dw) *dw = TO_DOUBLE(rp->drag->size.x);
2719 if (dh) *dh = TO_DOUBLE(rp->drag->size.y);
2720 return EINA_TRUE;
2721}
2722
2723EAPI Eina_Bool
2724edje_object_part_drag_step_set(Evas_Object *obj, const char *part, double dx, double dy)
2725{
2726 Edje *ed;
2727 Edje_Real_Part *rp;
2728
2729 ed = _edje_fetch(obj);
2730 if ((!ed) || (!part)) return EINA_FALSE;
2731 rp = _edje_real_part_recursive_get(ed, (char *)part);
2732 if (!rp) return EINA_FALSE;
2733 if (!rp->drag) return EINA_FALSE;
2734 if (dx < 0.0) dx = 0.0;
2735 else if (dx > 1.0) dx = 1.0;
2736 if (dy < 0.0) dy = 0.0;
2737 else if (dy > 1.0) dy = 1.0;
2738 rp->drag->step.x = FROM_DOUBLE(dx);
2739 rp->drag->step.y = FROM_DOUBLE(dy);
2740#ifdef EDJE_CALC_CACHE
2741 rp->invalidate = 1;
2742#endif
2743 return EINA_TRUE;
2744}
2745
2746EAPI Eina_Bool
2747edje_object_part_drag_step_get(const Evas_Object *obj, const char *part, double *dx, double *dy)
2748{
2749 Edje *ed;
2750 Edje_Real_Part *rp;
2751
2752 ed = _edje_fetch(obj);
2753 if ((!ed) || (!part))
2754 {
2755 if (dx) *dx = 0;
2756 if (dy) *dy = 0;
2757 return EINA_FALSE;
2758 }
2759
2760 /* Need to recalc before providing the object. */
2761 _edje_recalc_do(ed);
2762
2763 rp = _edje_real_part_recursive_get(ed, (char *)part);
2764 if (!rp || !rp->drag)
2765 {
2766 if (dx) *dx = 0;
2767 if (dy) *dy = 0;
2768 return EINA_FALSE;
2769 }
2770 if (dx) *dx = TO_DOUBLE(rp->drag->step.x);
2771 if (dy) *dy = TO_DOUBLE(rp->drag->step.y);
2772 return EINA_TRUE;
2773}
2774
2775EAPI Eina_Bool
2776edje_object_part_drag_page_set(Evas_Object *obj, const char *part, double dx, double dy)
2777{
2778 Edje *ed;
2779 Edje_Real_Part *rp;
2780
2781 ed = _edje_fetch(obj);
2782 if ((!ed) || (!part)) return EINA_FALSE;
2783 rp = _edje_real_part_recursive_get(ed, (char *)part);
2784 if (!rp) return EINA_FALSE;
2785 if (!rp->drag) return EINA_FALSE;
2786 if (dx < 0.0) dx = 0.0;
2787 else if (dx > 1.0) dx = 1.0;
2788 if (dy < 0.0) dy = 0.0;
2789 else if (dy > 1.0) dy = 1.0;
2790 rp->drag->page.x = FROM_DOUBLE(dx);
2791 rp->drag->page.y = FROM_DOUBLE(dy);
2792#ifdef EDJE_CALC_CACHE
2793 rp->invalidate = 1;
2794#endif
2795 return EINA_TRUE;
2796}
2797
2798EAPI Eina_Bool
2799edje_object_part_drag_page_get(const Evas_Object *obj, const char *part, double *dx, double *dy)
2800{
2801 Edje *ed;
2802 Edje_Real_Part *rp;
2803
2804 ed = _edje_fetch(obj);
2805 if ((!ed) || (!part))
2806 {
2807 if (dx) *dx = 0;
2808 if (dy) *dy = 0;
2809 return EINA_FALSE;
2810 }
2811
2812 /* Need to recalc before providing the object. */
2813 _edje_recalc_do(ed);
2814
2815 rp = _edje_real_part_recursive_get(ed, (char *)part);
2816 if (!rp || !rp->drag)
2817 {
2818 if (dx) *dx = 0;
2819 if (dy) *dy = 0;
2820 return EINA_FALSE;
2821 }
2822 if (dx) *dx = TO_DOUBLE(rp->drag->page.x);
2823 if (dy) *dy = TO_DOUBLE(rp->drag->page.y);
2824 return EINA_TRUE;
2825}
2826
2827EAPI Eina_Bool
2828edje_object_part_drag_step(Evas_Object *obj, const char *part, double dx, double dy)
2829{
2830 Edje *ed;
2831 Edje_Real_Part *rp;
2832 FLOAT_T px, py;
2833
2834 ed = _edje_fetch(obj);
2835 if ((!ed) || (!part)) return EINA_FALSE;
2836 rp = _edje_real_part_recursive_get(ed, (char *)part);
2837 if (!rp) return EINA_FALSE;
2838 if (!rp->drag) return EINA_FALSE;
2839 if (rp->drag->down.count > 0) return EINA_FALSE;
2840 px = rp->drag->val.x;
2841 py = rp->drag->val.y;
2842 rp->drag->val.x = ADD(px, MUL(FROM_DOUBLE(dx),
2843 MUL(rp->drag->step.x, rp->part->dragable.x)));
2844 rp->drag->val.y = ADD(py, MUL(FROM_DOUBLE(dy),
2845 MUL(rp->drag->step.y, rp->part->dragable.y)));
2846 rp->drag->val.x = CLAMP (rp->drag->val.x, ZERO, FROM_DOUBLE(1.0));
2847 rp->drag->val.y = CLAMP (rp->drag->val.y, ZERO, FROM_DOUBLE(1.0));
2848 if ((px == rp->drag->val.x) && (py == rp->drag->val.y)) return EINA_TRUE;
2849#ifdef EDJE_CALC_CACHE
2850 rp->invalidate = 1;
2851#endif
2852 _edje_dragable_pos_set(rp->edje, rp, rp->drag->val.x, rp->drag->val.y);
2853 _edje_emit(rp->edje, "drag,step", rp->part->name);
2854 return EINA_TRUE;
2855}
2856
2857EAPI Eina_Bool
2858edje_object_part_drag_page(Evas_Object *obj, const char *part, double dx, double dy)
2859{
2860 Edje *ed;
2861 Edje_Real_Part *rp;
2862 FLOAT_T px, py;
2863
2864 ed = _edje_fetch(obj);
2865 if ((!ed) || (!part)) return EINA_FALSE;
2866 rp = _edje_real_part_recursive_get(ed, (char *)part);
2867 if (!rp) return EINA_FALSE;
2868 if (!rp->drag) return EINA_FALSE;
2869 if (rp->drag->down.count > 0) return EINA_FALSE;
2870 px = rp->drag->val.x;
2871 py = rp->drag->val.y;
2872 rp->drag->val.x = ADD(px, MUL(FROM_DOUBLE(dx), MUL(rp->drag->page.x, rp->part->dragable.x)));
2873 rp->drag->val.y = ADD(py, MUL(FROM_DOUBLE(dy), MUL(rp->drag->page.y, rp->part->dragable.y)));
2874 rp->drag->val.x = CLAMP (rp->drag->val.x, ZERO, FROM_DOUBLE(1.0));
2875 rp->drag->val.y = CLAMP (rp->drag->val.y, ZERO, FROM_DOUBLE(1.0));
2876 if ((px == rp->drag->val.x) && (py == rp->drag->val.y)) return EINA_TRUE;
2877#ifdef EDJE_CALC_CACHE
2878 rp->invalidate = 1;
2879#endif
2880 _edje_dragable_pos_set(rp->edje, rp, rp->drag->val.x, rp->drag->val.y);
2881 _edje_emit(rp->edje, "drag,page", rp->part->name);
2882 return EINA_TRUE;
2883}
2884
2885void
2886_edje_box_init(void)
2887{
2888
2889}
2890
2891void
2892_edje_box_shutdown(void)
2893{
2894 if (!_edje_box_layout_registry)
2895 return;
2896
2897 eina_rbtree_delete
2898 (_edje_box_layout_registry, _edje_box_layout_external_free, NULL);
2899 _edje_box_layout_registry = NULL;
2900}
2901
2902EAPI Eina_Bool
2903edje_object_part_box_append(Evas_Object *obj, const char *part, Evas_Object *child)
2904{
2905 Edje *ed;
2906 Edje_Real_Part *rp;
2907
2908 ed = _edje_fetch(obj);
2909 if ((!ed) || (!part) || (!child)) return EINA_FALSE;
2910
2911 rp = _edje_real_part_recursive_get(ed, part);
2912 if (!rp) return EINA_FALSE;
2913 if (rp->part->type != EDJE_PART_TYPE_BOX) return EINA_FALSE;
2914
2915 return _edje_real_part_box_append(rp, child);
2916}
2917
2918EAPI Eina_Bool
2919edje_object_part_box_prepend(Evas_Object *obj, const char *part, Evas_Object *child)
2920{
2921 Edje *ed;
2922 Edje_Real_Part *rp;
2923
2924 ed = _edje_fetch(obj);
2925 if ((!ed) || (!part)) return EINA_FALSE;
2926
2927 rp = _edje_real_part_recursive_get(ed, part);
2928 if (!rp) return EINA_FALSE;
2929 if (rp->part->type != EDJE_PART_TYPE_BOX) return EINA_FALSE;
2930
2931 return _edje_real_part_box_prepend(rp, child);
2932}
2933
2934EAPI Eina_Bool
2935edje_object_part_box_insert_before(Evas_Object *obj, const char *part, Evas_Object *child, const Evas_Object *reference)
2936{
2937 Edje *ed;
2938 Edje_Real_Part *rp;
2939
2940 ed = _edje_fetch(obj);
2941 if ((!ed) || (!part)) return EINA_FALSE;
2942
2943 rp = _edje_real_part_recursive_get(ed, part);
2944 if (!rp) return EINA_FALSE;
2945 if (rp->part->type != EDJE_PART_TYPE_BOX) return EINA_FALSE;
2946
2947 return _edje_real_part_box_insert_before(rp, child, reference);
2948}
2949
2950EAPI Eina_Bool
2951edje_object_part_box_insert_at(Evas_Object *obj, const char *part, Evas_Object *child, unsigned int pos)
2952{
2953 Edje *ed;
2954 Edje_Real_Part *rp;
2955
2956 ed = _edje_fetch(obj);
2957 if ((!ed) || (!part)) return EINA_FALSE;
2958
2959 rp = _edje_real_part_recursive_get(ed, part);
2960 if (!rp) return EINA_FALSE;
2961 if (rp->part->type != EDJE_PART_TYPE_BOX) return EINA_FALSE;
2962
2963 return _edje_real_part_box_insert_at(rp, child, pos);
2964}
2965
2966EAPI Evas_Object *
2967edje_object_part_box_remove(Evas_Object *obj, const char *part, Evas_Object *child)
2968{
2969 Edje *ed;
2970 Edje_Real_Part *rp;
2971
2972 ed = _edje_fetch(obj);
2973 if ((!ed) || (!part)) return NULL;
2974
2975 rp = _edje_real_part_recursive_get(ed, part);
2976 if (!rp) return NULL;
2977 if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
2978
2979 return _edje_real_part_box_remove(rp, child);
2980}
2981
2982EAPI Evas_Object *
2983edje_object_part_box_remove_at(Evas_Object *obj, const char *part, unsigned int pos)
2984{
2985 Edje *ed;
2986 Edje_Real_Part *rp;
2987
2988 ed = _edje_fetch(obj);
2989 if ((!ed) || (!part)) return NULL;
2990
2991 rp = _edje_real_part_recursive_get(ed, part);
2992 if (!rp) return NULL;
2993 if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
2994
2995 return _edje_real_part_box_remove_at(rp, pos);
2996}
2997
2998EAPI Eina_Bool
2999edje_object_part_box_remove_all(Evas_Object *obj, const char *part, Eina_Bool clear)
3000{
3001 Edje *ed;
3002 Edje_Real_Part *rp;
3003
3004 ed = _edje_fetch(obj);
3005 if ((!ed) || (!part)) return EINA_FALSE;
3006
3007 rp = _edje_real_part_recursive_get(ed, part);
3008 if (!rp) return EINA_FALSE;
3009 if (rp->part->type != EDJE_PART_TYPE_BOX) return EINA_FALSE;
3010
3011 return _edje_real_part_box_remove_all(rp, clear);
3012
3013}
3014
3015static void
3016_edje_box_child_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *child __UNUSED__, void *einfo __UNUSED__)
3017{
3018 Edje_Real_Part *rp = data;
3019
3020 rp->edje->dirty = 1;
3021#ifdef EDJE_CALC_CACHE
3022 rp->invalidate = 1;
3023#endif
3024 _edje_recalc(rp->edje);
3025}
3026
3027static void
3028_edje_box_child_add(Edje_Real_Part *rp, Evas_Object *child)
3029{
3030 evas_object_event_callback_add
3031 (child, EVAS_CALLBACK_DEL, _edje_box_child_del_cb, rp);
3032
3033 rp->edje->dirty = 1;
3034#ifdef EDJE_CALC_CACHE
3035 rp->invalidate = 1;
3036#endif
3037 _edje_recalc(rp->edje);
3038}
3039
3040static void
3041_edje_box_child_remove(Edje_Real_Part *rp, Evas_Object *child)
3042{
3043 evas_object_event_callback_del_full
3044 (child, EVAS_CALLBACK_DEL, _edje_box_child_del_cb, rp);
3045
3046 rp->edje->dirty = 1;
3047#ifdef EDJE_CALC_CACHE
3048 rp->invalidate = 1;
3049#endif
3050 _edje_recalc(rp->edje);
3051}
3052
3053Eina_Bool
3054_edje_real_part_box_append(Edje_Real_Part *rp, Evas_Object *child_obj)
3055{
3056 Evas_Object_Box_Option *opt;
3057
3058 opt = evas_object_box_append(rp->object, child_obj);
3059 if (!opt) return EINA_FALSE;
3060
3061 if (!_edje_box_layout_add_child(rp, child_obj))
3062 {
3063 evas_object_box_remove(rp->object, child_obj);
3064 return EINA_FALSE;
3065 }
3066
3067 _edje_box_child_add(rp, child_obj);
3068
3069 return EINA_TRUE;
3070}
3071
3072Eina_Bool
3073_edje_real_part_box_prepend(Edje_Real_Part *rp, Evas_Object *child_obj)
3074{
3075 Evas_Object_Box_Option *opt;
3076
3077 opt = evas_object_box_prepend(rp->object, child_obj);
3078 if (!opt) return EINA_FALSE;
3079
3080 if (!_edje_box_layout_add_child(rp, child_obj))
3081 {
3082 evas_object_box_remove(rp->object, child_obj);
3083 return EINA_FALSE;
3084 }
3085
3086 _edje_box_child_add(rp, child_obj);
3087
3088 return EINA_TRUE;
3089}
3090
3091Eina_Bool
3092_edje_real_part_box_insert_before(Edje_Real_Part *rp, Evas_Object *child_obj, const Evas_Object *ref)
3093{
3094 Evas_Object_Box_Option *opt;
3095
3096 opt = evas_object_box_insert_before(rp->object, child_obj, ref);
3097 if (!opt) return EINA_FALSE;
3098
3099 if (!_edje_box_layout_add_child(rp, child_obj))
3100 {
3101 evas_object_box_remove(rp->object, child_obj);
3102 return EINA_FALSE;
3103 }
3104
3105 _edje_box_child_add(rp, child_obj);
3106
3107 return EINA_TRUE;
3108}
3109
3110Eina_Bool
3111_edje_real_part_box_insert_at(Edje_Real_Part *rp, Evas_Object *child_obj, unsigned int pos)
3112{
3113 Evas_Object_Box_Option *opt;
3114
3115 opt = evas_object_box_insert_at(rp->object, child_obj, pos);
3116 if (!opt) return EINA_FALSE;
3117
3118 if (!_edje_box_layout_add_child(rp, child_obj))
3119 {
3120 evas_object_box_remove(rp->object, child_obj);
3121 return EINA_FALSE;
3122 }
3123
3124 _edje_box_child_add(rp, child_obj);
3125
3126 return EINA_TRUE;
3127}
3128
3129Evas_Object *
3130_edje_real_part_box_remove(Edje_Real_Part *rp, Evas_Object *child_obj)
3131{
3132 if (evas_object_data_get(child_obj, "\377 edje.box_item")) return NULL;
3133 if (!evas_object_box_remove(rp->object, child_obj)) return NULL;
3134 _edje_box_layout_remove_child(rp, child_obj);
3135 _edje_box_child_remove(rp, child_obj);
3136 return child_obj;
3137}
3138
3139Evas_Object *
3140_edje_real_part_box_remove_at(Edje_Real_Part *rp, unsigned int pos)
3141{
3142 Evas_Object_Box_Option *opt;
3143 Evas_Object_Box_Data *priv;
3144 Evas_Object *child_obj;
3145
3146 priv = evas_object_smart_data_get(rp->object);
3147 opt = eina_list_nth(priv->children, pos);
3148 if (!opt) return NULL;
3149 child_obj = opt->obj;
3150 if (evas_object_data_get(child_obj, "\377 edje.box_item")) return NULL;
3151 if (!evas_object_box_remove_at(rp->object, pos)) return NULL;
3152 _edje_box_layout_remove_child(rp, child_obj);
3153 _edje_box_child_remove(rp, child_obj);
3154 return child_obj;
3155}
3156
3157Eina_Bool
3158_edje_real_part_box_remove_all(Edje_Real_Part *rp, Eina_Bool clear)
3159{
3160 Eina_List *children;
3161 int i = 0;
3162
3163 children = evas_object_box_children_get(rp->object);
3164 while (children)
3165 {
3166 Evas_Object *child_obj = children->data;
3167 if (evas_object_data_get(child_obj, "\377 edje.box_item"))
3168 i++;
3169 else
3170 {
3171 _edje_box_layout_remove_child(rp, child_obj);
3172 _edje_box_child_remove(rp, child_obj);
3173 if (!evas_object_box_remove_at(rp->object, i))
3174 return EINA_FALSE;
3175 if (clear)
3176 evas_object_del(child_obj);
3177 }
3178 children = eina_list_remove_list(children, children);
3179 }
3180 return EINA_TRUE;
3181}
3182
3183static void
3184_edje_table_child_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *child __UNUSED__, void *einfo __UNUSED__)
3185{
3186 Edje_Real_Part *rp = data;
3187
3188 rp->edje->dirty = 1;
3189#ifdef EDJE_CALC_CACHE
3190 rp->invalidate = 1;
3191#endif
3192 _edje_recalc(rp->edje);
3193}
3194
3195static void
3196_edje_table_child_add(Edje_Real_Part *rp, Evas_Object *child)
3197{
3198 evas_object_event_callback_add
3199 (child, EVAS_CALLBACK_DEL, _edje_table_child_del_cb, rp);
3200
3201 rp->edje->dirty = 1;
3202#ifdef EDJE_CALC_CACHE
3203 rp->invalidate = 1;
3204#endif
3205 _edje_recalc(rp->edje);
3206}
3207
3208static void
3209_edje_table_child_remove(Edje_Real_Part *rp, Evas_Object *child)
3210{
3211 evas_object_event_callback_del_full
3212 (child, EVAS_CALLBACK_DEL, _edje_table_child_del_cb, rp);
3213
3214 rp->edje->dirty = 1;
3215#ifdef EDJE_CALC_CACHE
3216 rp->invalidate = 1;
3217#endif
3218 _edje_recalc(rp->edje);
3219}
3220
3221EAPI Evas_Object *
3222edje_object_part_table_child_get(Evas_Object *obj, const char *part, unsigned int col, unsigned int row)
3223{
3224 Edje *ed;
3225 Edje_Real_Part *rp;
3226
3227 ed = _edje_fetch(obj);
3228 if ((!ed) || (!part)) return NULL;
3229
3230 rp = _edje_real_part_recursive_get(ed, part);
3231 if (!rp) return NULL;
3232 if (rp->part->type != EDJE_PART_TYPE_TABLE) return NULL;
3233
3234 return evas_object_table_child_get(rp->object, col, row);
3235}
3236
3237EAPI Eina_Bool
3238edje_object_part_table_pack(Evas_Object *obj, const char *part, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
3239{
3240 Edje *ed;
3241 Edje_Real_Part *rp;
3242
3243 ed = _edje_fetch(obj);
3244 if ((!ed) || (!part)) return EINA_FALSE;
3245
3246 rp = _edje_real_part_recursive_get(ed, part);
3247 if (!rp) return EINA_FALSE;
3248 if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
3249
3250 return _edje_real_part_table_pack(rp, child_obj, col, row, colspan, rowspan);
3251}
3252
3253EAPI Eina_Bool
3254edje_object_part_table_unpack(Evas_Object *obj, const char *part, Evas_Object *child_obj)
3255{
3256 Edje *ed;
3257 Edje_Real_Part *rp;
3258
3259 ed = _edje_fetch(obj);
3260 if ((!ed) || (!part)) return EINA_FALSE;
3261
3262 rp = _edje_real_part_recursive_get(ed, part);
3263 if (!rp) return EINA_FALSE;
3264 if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
3265
3266 return _edje_real_part_table_unpack(rp, child_obj);
3267}
3268
3269EAPI Eina_Bool
3270edje_object_part_table_col_row_size_get(const Evas_Object *obj, const char *part, int *cols, int *rows)
3271{
3272 Edje *ed;
3273 Edje_Real_Part *rp;
3274
3275 ed = _edje_fetch(obj);
3276 if ((!ed) || (!part)) return EINA_FALSE;
3277
3278 rp = _edje_real_part_recursive_get(ed, part);
3279 if (!rp) return EINA_FALSE;
3280 if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
3281
3282 evas_object_table_col_row_size_get(rp->object, cols, rows);
3283 return EINA_TRUE;
3284}
3285
3286EAPI Eina_Bool
3287edje_object_part_table_clear(Evas_Object *obj, const char *part, Eina_Bool clear)
3288{
3289 Edje *ed;
3290 Edje_Real_Part *rp;
3291
3292 ed = _edje_fetch(obj);
3293 if ((!ed) || (!part)) return EINA_FALSE;
3294
3295 rp = _edje_real_part_recursive_get(ed, part);
3296 if (!rp) return EINA_FALSE;
3297 if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
3298
3299 _edje_real_part_table_clear(rp, clear);
3300 return EINA_TRUE;
3301}
3302
3303static void
3304_edje_perspective_obj_del(void *data, __UNUSED__ Evas *e, __UNUSED__ Evas_Object *obj, __UNUSED__ void *event_info)
3305{
3306 Edje_Perspective *ps = data;
3307 Evas_Object *o;
3308
3309 EINA_LIST_FREE(ps->users, o)
3310 {
3311 Edje *ed;
3312
3313 ed = evas_object_smart_data_get(o);
3314 if (!ed) continue;
3315 ed->persp = NULL;
3316 ed->dirty = 1;
3317 _edje_recalc_do(ed);
3318 }
3319 free(ps);
3320}
3321
3322EAPI Edje_Perspective *
3323edje_perspective_new(Evas *e)
3324{
3325 Edje_Perspective *ps;
3326 Evas_Coord vx, vy, vw, vh;
3327
3328 if (!e) return NULL;
3329 ps = calloc(1, sizeof(Edje_Perspective));
3330 ps->obj = evas_object_rectangle_add(e);
3331 evas_object_data_set(ps->obj, "_edje_perspective", ps);
3332 evas_object_event_callback_add(ps->obj, EVAS_CALLBACK_DEL, _edje_perspective_obj_del, ps);
3333 evas_output_viewport_get(e, &vx, &vy, &vw, &vh);
3334 ps->e = e;
3335 ps->px = vx + (vw / 2);
3336 ps->py = vy + (vh / 2);
3337 ps->z0 = 0;
3338 ps->foc = 1000;
3339 return ps;
3340}
3341
3342EAPI void
3343edje_perspective_free(Edje_Perspective *ps)
3344{
3345 if (!ps) return;
3346 evas_object_del(ps->obj);
3347}
3348
3349EAPI void
3350edje_perspective_set(Edje_Perspective *ps, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc)
3351{
3352 Eina_List *l;
3353 Evas_Object *o;
3354
3355 if (!ps) return;
3356 if ((ps->px == px) && (ps->py == py) && (ps->z0 == z0) && (ps->foc == foc)) return;
3357 ps->px = px;
3358 ps->py = py;
3359 ps->z0 = z0;
3360 ps->foc = foc;
3361 EINA_LIST_FOREACH(ps->users, l, o)
3362 {
3363 Edje *ed;
3364
3365 ed = evas_object_smart_data_get(o);
3366 if (!ed) continue;
3367 if (!ed->persp)
3368 {
3369 ed->dirty = 1;
3370 _edje_recalc_do(ed);
3371 }
3372 }
3373 if (ps->global)
3374 {
3375 EINA_LIST_FOREACH(_edje_edjes, l, o)
3376 {
3377 Edje *ed;
3378
3379 ed = evas_object_smart_data_get(o);
3380 if (!ed) continue;
3381 if (!ed->persp)
3382 {
3383 ed->dirty = 1;
3384 _edje_recalc_do(ed);
3385 }
3386 }
3387 }
3388}
3389
3390EAPI void
3391edje_perspective_global_set(Edje_Perspective *ps, Eina_Bool global)
3392{
3393 Evas_Object *o;
3394 Eina_List *l;
3395
3396 if (!ps) return;
3397 if (ps->global == global) return;
3398 if (global)
3399 {
3400 o = evas_object_name_find(evas_object_evas_get(ps->obj),
3401 "_edje_perspective");
3402 if (o) evas_object_name_set(o, NULL);
3403 evas_object_name_set(ps->obj, "_edje_perspective");
3404 }
3405 else
3406 evas_object_name_set(ps->obj, NULL);
3407 ps->global = global;
3408 EINA_LIST_FOREACH(_edje_edjes, l, o)
3409 {
3410 Edje *ed;
3411
3412 ed = evas_object_smart_data_get(o);
3413 if (!ed) continue;
3414 if (!ed->persp)
3415 {
3416 ed->dirty = 1;
3417 _edje_recalc_do(ed);
3418 }
3419 }
3420}
3421
3422EAPI Eina_Bool
3423edje_perspective_global_get(const Edje_Perspective *ps)
3424{
3425 if (!ps) return EINA_FALSE;
3426 return ps->global;
3427}
3428
3429EAPI const Edje_Perspective *
3430edje_evas_global_perspective_get(const Evas *e)
3431{
3432 Evas_Object *obj;
3433
3434 if (!e) return NULL;
3435 obj = evas_object_name_find(e, "_edje_perspective");
3436 if (!obj) return NULL;
3437 return evas_object_data_get(obj, "_edje_perspective");
3438}
3439
3440EAPI void
3441edje_object_perspective_set(Evas_Object *obj, Edje_Perspective *ps)
3442{
3443 Edje *ed;
3444
3445 ed = evas_object_smart_data_get(obj);
3446 if (!ed) return;
3447 if (ed->persp == ps) return;
3448 if (ed->persp != ps)
3449 {
3450 if (ed->persp)
3451 ed->persp->users = eina_list_remove(ed->persp->users, obj);
3452 }
3453 ed->persp = ps;
3454 if (ps) ps->users = eina_list_append(ps->users, obj);
3455 ed->dirty = 1;
3456 _edje_recalc_do(ed);
3457}
3458
3459EAPI const Edje_Perspective *
3460edje_object_perspective_get(const Evas_Object *obj)
3461{
3462 Edje *ed;
3463
3464 ed = evas_object_smart_data_get(obj);
3465 if (!ed) return NULL;
3466 return ed->persp;
3467}
3468
3469#define EDJE_PRELOAD_EMISSION "preload,done"
3470#define EDJE_PRELOAD_SOURCE NULL
3471
3472EAPI Eina_Bool
3473edje_object_preload(Evas_Object *obj, Eina_Bool cancel)
3474{
3475 Edje *ed;
3476 int count;
3477 unsigned int i;
3478
3479 ed = _edje_fetch(obj);
3480 if (!ed) return EINA_FALSE;
3481
3482 _edje_recalc_do(ed);
3483
3484 for (i = 0, count = 0; i < ed->table_parts_size; i++)
3485 {
3486 Edje_Real_Part *rp;
3487 Edje_Part *ep;
3488
3489 rp = ed->table_parts[i];
3490 ep = rp->part;
3491
3492 if (ep->type == EDJE_PART_TYPE_IMAGE ||
3493 (ep->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object))
3494 count++;
3495 }
3496
3497 ed->preload_count = count;
3498
3499 if (count > 0)
3500 {
3501 for (i = 0; i < ed->table_parts_size; i++)
3502 {
3503 Edje_Real_Part *rp;
3504 Edje_Part *ep;
3505
3506 rp = ed->table_parts[i];
3507 ep = rp->part;
3508
3509 if (ep->type == EDJE_PART_TYPE_IMAGE)
3510 {
3511 const char *file = NULL;
3512 const char *key = NULL;
3513
3514 evas_object_event_callback_del_full(rp->object, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
3515
3516 evas_object_image_file_get(rp->object, &file, &key);
3517 if (!file && !key)
3518 {
3519 ed->preload_count--;
3520 }
3521 else
3522 {
3523 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
3524 evas_object_image_preload(rp->object, cancel);
3525 }
3526 count--;
3527 }
3528 else if (ep->type == EDJE_PART_TYPE_GROUP)
3529 {
3530 if (rp->swallowed_object) {
3531 edje_object_signal_callback_del(rp->swallowed_object, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE, _edje_object_signal_preload_cb);
3532 edje_object_signal_callback_add(rp->swallowed_object, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE, _edje_object_signal_preload_cb, ed);
3533 edje_object_preload(rp->swallowed_object, cancel);
3534
3535 count--;
3536 }
3537 }
3538 }
3539 }
3540 else
3541 {
3542 _edje_emit(ed, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE);
3543 }
3544
3545 return EINA_TRUE;
3546}
3547
3548Eina_Bool
3549_edje_real_part_table_pack(Edje_Real_Part *rp, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
3550{
3551 Eina_Bool ret =
3552 evas_object_table_pack(rp->object, child_obj, col, row, colspan, rowspan);
3553
3554 _edje_table_child_add(rp, child_obj);
3555
3556 return ret;
3557}
3558
3559Eina_Bool
3560_edje_real_part_table_unpack(Edje_Real_Part *rp, Evas_Object *child_obj)
3561{
3562 Eina_Bool ret = evas_object_table_unpack(rp->object, child_obj);
3563
3564 if (ret)
3565 _edje_table_child_remove(rp, child_obj);
3566
3567 return ret;
3568}
3569
3570void
3571_edje_real_part_table_clear(Edje_Real_Part *rp, Eina_Bool clear)
3572{
3573 Eina_List *children;
3574
3575 children = evas_object_table_children_get(rp->object);
3576 while (children)
3577 {
3578 Evas_Object *child_obj = children->data;
3579
3580 _edje_table_child_remove(rp, child_obj);
3581 if (!evas_object_data_get(child_obj, "\377 edje.table_item"))
3582 {
3583 evas_object_table_unpack(rp->object, child_obj);
3584 if (clear)
3585 evas_object_del(child_obj);
3586 }
3587 children = eina_list_remove_list(children, children);
3588 }
3589}
3590
3591Edje_Real_Part *
3592_edje_real_part_recursive_get(const Edje *ed, const char *part)
3593{
3594 Edje_Real_Part *rp;
3595 char **path;
3596
3597 path = eina_str_split(part, EDJE_PART_PATH_SEPARATOR_STRING, 0);
3598 if (!path) return NULL;
3599
3600 rp = _edje_real_part_recursive_get_helper(ed, path);
3601
3602 free(*path);
3603 free(path);
3604 return rp;
3605}
3606
3607Evas_Object *
3608_edje_children_get(Edje_Real_Part *rp, const char *partid)
3609{
3610 Evas_Object *child;
3611 Eina_List *l;
3612 long int v;
3613 char *p;
3614
3615 if (!partid) return NULL;
3616
3617 switch (rp->part->type)
3618 {
3619 case EDJE_PART_TYPE_EXTERNAL:
3620 return _edje_external_content_get(rp->swallowed_object, partid);
3621 case EDJE_PART_TYPE_BOX:
3622 l = evas_object_box_children_get(rp->object);
3623 break;
3624 case EDJE_PART_TYPE_TABLE:
3625 l = evas_object_table_children_get(rp->object);
3626 break;
3627 default:
3628 return NULL;
3629 }
3630
3631 v = strtol(partid, &p, 10);
3632 if ((*p == '\0') && (v >= 0))
3633 {
3634 child = eina_list_nth(l, v);
3635 }
3636 else
3637 {
3638 Evas_Object *cur;
3639 child = NULL;
3640 EINA_LIST_FREE(l, cur)
3641 {
3642 const char *name = evas_object_name_get(cur);
3643 if ((name) && (!strcmp(name, partid)))
3644 {
3645 child = cur;
3646 break;
3647 }
3648 }
3649 }
3650 eina_list_free(l);
3651
3652 return child;
3653}
3654
3655/* rebuild alternative path */
3656char *
3657_edje_merge_path(const char *alias, char * const *path)
3658{
3659 char *tmp;
3660 unsigned int length = 1;
3661 unsigned int alias_length;
3662 unsigned int i;
3663
3664 if (!alias) return NULL;
3665
3666 alias_length = strlen(alias);
3667
3668 for (i = 0; path[i]; i++)
3669 length += strlen(path[i]) + 1;
3670
3671 tmp = malloc(sizeof (char) * (length + alias_length + 2));
3672 memcpy(tmp, alias, alias_length);
3673 tmp[alias_length] = '\0';
3674
3675 for (i = 0; path[i]; i++)
3676 {
3677 strcat(tmp, EDJE_PART_PATH_SEPARATOR_STRING);
3678 strcat(tmp, path[i]);
3679 }
3680
3681 return tmp;
3682}
3683
3684
3685Edje_Real_Part *
3686_edje_real_part_recursive_get_helper(const Edje *ed, char **path)
3687{
3688 Edje_Real_Part *rp;
3689 Evas_Object *child;
3690 char *idx = NULL;
3691
3692 if (!path[0])
3693 return NULL;
3694
3695 if (ed->collection && ed->collection->alias)
3696 {
3697 char *alias;
3698
3699 alias = _edje_merge_path(eina_hash_find(ed->collection->alias, path[0]), path + 1);
3700 if (alias) {
3701 rp = _edje_real_part_recursive_get(ed, alias);
3702 free(alias);
3703 return rp;
3704 }
3705 }
3706
3707 //printf(" lookup: %s on %s\n", path[0], ed->parent ? ed->parent : "-");
3708 idx = strchr(path[0], EDJE_PART_PATH_SEPARATOR_INDEXL);
3709 if (idx)
3710 {
3711 char *end;
3712
3713 end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR);
3714 if (end)
3715 {
3716 *end = '\0';
3717 *idx = '\0';
3718 idx++;
3719 }
3720 }
3721
3722 rp = _edje_real_part_get(ed, path[0]);
3723 if (!path[1] && !idx) return rp;
3724 if (!rp) return NULL;
3725
3726 switch (rp->part->type)
3727 {
3728 case EDJE_PART_TYPE_GROUP:
3729 if (!rp->swallowed_object) return NULL;
3730 ed = _edje_fetch(rp->swallowed_object);
3731 if (!ed) return NULL;
3732 path++;
3733 return _edje_real_part_recursive_get_helper(ed, path);
3734 case EDJE_PART_TYPE_BOX:
3735 case EDJE_PART_TYPE_TABLE:
3736 case EDJE_PART_TYPE_EXTERNAL:
3737 if (!idx) return rp;
3738 path++;
3739
3740 child = _edje_children_get(rp, idx);
3741
3742 ed = _edje_fetch(child);
3743
3744 if (!ed) return NULL;
3745 return _edje_real_part_recursive_get_helper(ed, path);
3746 default:
3747 return NULL;
3748 }
3749}
3750
3751/* Private Routines */
3752Edje_Real_Part *
3753_edje_real_part_get(const Edje *ed, const char *part)
3754{
3755 unsigned int i;
3756
3757 if (!part) return NULL;
3758
3759 for (i = 0; i < ed->table_parts_size; i++)
3760 {
3761 Edje_Real_Part *rp;
3762
3763 rp = ed->table_parts[i];
3764 if ((rp->part->name) && (!strcmp(rp->part->name, part))) return rp;
3765 }
3766 return NULL;
3767}
3768
3769Edje_Color_Class *
3770_edje_color_class_find(Edje *ed, const char *color_class)
3771{
3772 Eina_List *l;
3773 Edje_Color_Class *cc = NULL;
3774
3775 if ((!ed) || (!color_class)) return NULL;
3776
3777 /* first look through the object scope */
3778 EINA_LIST_FOREACH(ed->color_classes, l, cc)
3779 if ((cc->name) && (!strcmp(color_class, cc->name))) return cc;
3780
3781 /* next look through the global scope */
3782 cc = eina_hash_find(_edje_color_class_hash, color_class);
3783 if (cc) return cc;
3784
3785 /* finally, look through the file scope */
3786 EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
3787 if ((cc->name) && (!strcmp(color_class, cc->name))) return cc;
3788
3789 return NULL;
3790}
3791
3792void
3793_edje_color_class_member_add(Edje *ed, const char *color_class)
3794{
3795 _edje_class_member_add(ed, &ed->members.color_class, &_edje_color_class_member_hash, color_class);
3796}
3797
3798void
3799_edje_color_class_member_direct_del(const char *color_class, void *l)
3800{
3801 _edje_class_member_direct_del(color_class, l, _edje_color_class_member_hash);
3802}
3803
3804void
3805_edje_color_class_member_del(Edje *ed, const char *color_class)
3806{
3807 if ((!ed) || (!color_class)) return;
3808
3809 _edje_class_member_del(&ed->members.color_class, &_edje_color_class_member_hash, color_class);
3810}
3811
3812void
3813_edje_color_class_members_free(void)
3814{
3815 if (!_edje_color_class_member_hash) return;
3816 eina_hash_foreach(_edje_color_class_member_hash, member_list_free, NULL);
3817 eina_hash_free(_edje_color_class_member_hash);
3818 _edje_color_class_member_hash = NULL;
3819}
3820
3821static Eina_Bool
3822color_class_hash_list_free(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
3823{
3824 Edje_Color_Class *cc;
3825
3826 cc = data;
3827 if (cc->name) eina_stringshare_del(cc->name);
3828 free(cc);
3829 return EINA_TRUE;
3830}
3831
3832void
3833_edje_color_class_hash_free(void)
3834{
3835 if (!_edje_color_class_hash) return;
3836 eina_hash_foreach(_edje_color_class_hash, color_class_hash_list_free, NULL);
3837 eina_hash_free(_edje_color_class_hash);
3838 _edje_color_class_hash = NULL;
3839}
3840
3841void
3842_edje_color_class_on_del(Edje *ed, Edje_Part *ep)
3843{
3844 unsigned int i;
3845
3846 if ((ep->default_desc) && (ep->default_desc->color_class))
3847 _edje_color_class_member_del(ed, ep->default_desc->color_class);
3848
3849 for (i = 0; i < ep->other.desc_count; ++i)
3850 if (ep->other.desc[i]->color_class)
3851 _edje_color_class_member_del(ed, ep->other.desc[i]->color_class);
3852}
3853
3854Edje_Text_Class *
3855_edje_text_class_find(Edje *ed, const char *text_class)
3856{
3857 Eina_List *l;
3858 Edje_Text_Class *tc;
3859
3860 if ((!ed) || (!text_class)) return NULL;
3861 EINA_LIST_FOREACH(ed->text_classes, l, tc)
3862 if ((tc->name) && (!strcmp(text_class, tc->name))) return tc;
3863 return eina_hash_find(_edje_text_class_hash, text_class);
3864}
3865
3866void
3867_edje_text_class_member_direct_del(const char *text_class,
3868 void *l)
3869{
3870 _edje_class_member_direct_del(text_class, l, _edje_text_class_member_hash);
3871}
3872
3873void
3874_edje_text_class_member_add(Edje *ed, const char *text_class)
3875{
3876 _edje_class_member_add(ed, &ed->members.text_class, &_edje_text_class_member_hash, text_class);
3877}
3878
3879void
3880_edje_text_class_member_del(Edje *ed, const char *text_class)
3881{
3882 if ((!ed) || (!text_class)) return;
3883
3884 _edje_class_member_del(&ed->members.text_class, &_edje_text_class_member_hash, text_class);
3885}
3886
3887void
3888_edje_text_class_members_free(void)
3889{
3890 _edje_class_members_free(&_edje_text_class_member_hash);
3891}
3892
3893static Eina_Bool
3894text_class_hash_list_free(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
3895{
3896 Edje_Text_Class *tc;
3897
3898 tc = data;
3899 if (tc->name) eina_stringshare_del(tc->name);
3900 if (tc->font) eina_stringshare_del(tc->font);
3901 free(tc);
3902 return EINA_TRUE;
3903}
3904
3905void
3906_edje_text_class_hash_free(void)
3907{
3908 if (!_edje_text_class_hash) return;
3909 eina_hash_foreach(_edje_text_class_hash, text_class_hash_list_free, NULL);
3910 eina_hash_free(_edje_text_class_hash);
3911 _edje_text_class_hash = NULL;
3912}
3913
3914Edje *
3915_edje_fetch(const Evas_Object *obj)
3916{
3917 Edje *ed;
3918
3919 if (!evas_object_smart_type_check(obj, "edje"))
3920 return NULL;
3921 ed = evas_object_smart_data_get(obj);
3922 if ((ed) && (ed->delete_me)) return NULL;
3923 return ed;
3924}
3925
3926int
3927_edje_freeze(Edje *ed)
3928{
3929 ed->freeze++;
3930// printf("FREEZE %i\n", ed->freeze);
3931 return ed->freeze;
3932}
3933
3934int
3935_edje_thaw(Edje *ed)
3936{
3937 ed->freeze--;
3938 if (ed->freeze < 0)
3939 {
3940// printf("-------------########### OVER THAW\n");
3941 ed->freeze = 0;
3942 }
3943 if ((ed->freeze == 0) && (ed->recalc))
3944 {
3945// printf("thaw recalc\n");
3946 _edje_recalc(ed);
3947 }
3948 return ed->freeze;
3949}
3950
3951int
3952_edje_block(Edje *ed)
3953{
3954 _edje_ref(ed);
3955 ed->block++;
3956 return ed->block;
3957}
3958
3959int
3960_edje_unblock(Edje *ed)
3961{
3962 int ret = 0;
3963
3964 if (!ed) return ret;
3965
3966 ed->block--;
3967 if (ed->block == 0) ed->block_break = 0;
3968 ret = ed->block;
3969 _edje_unref(ed);
3970 return ret;
3971}
3972
3973int
3974_edje_block_break(Edje *ed)
3975{
3976 if (ed->block_break) return 1;
3977 return 0;
3978}
3979
3980void
3981_edje_block_violate(Edje *ed)
3982{
3983 if (ed->block > 0) ed->block_break = 1;
3984}
3985
3986void
3987_edje_object_part_swallow_free_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
3988{
3989 Evas_Object *edje_obj;
3990
3991 edje_obj = data;
3992 edje_object_part_unswallow(edje_obj, obj);
3993 return;
3994}
3995
3996static void
3997_edje_real_part_swallow_hints_update(Edje_Real_Part *rp)
3998{
3999 const char *type;
4000
4001 type = evas_object_type_get(rp->swallowed_object);
4002
4003 rp->swallow_params.min.w = 0;
4004 rp->swallow_params.min.h = 0;
4005 rp->swallow_params.max.w = -1;
4006 rp->swallow_params.max.h = -1;
4007 if ((type) && (!strcmp(type, "edje")))
4008 {
4009 Evas_Coord w, h;
4010
4011 edje_object_size_min_get(rp->swallowed_object, &w, &h);
4012 rp->swallow_params.min.w = w;
4013 rp->swallow_params.min.h = h;
4014 edje_object_size_max_get(rp->swallowed_object, &w, &h);
4015 rp->swallow_params.max.w = w;
4016 rp->swallow_params.max.h = h;
4017 }
4018 else if ((type) && ((!strcmp(type, "text")) || (!strcmp(type, "polygon")) ||
4019 (!strcmp(type, "line"))))
4020 {
4021 Evas_Coord w, h;
4022
4023 evas_object_geometry_get(rp->swallowed_object, NULL, NULL, &w, &h);
4024 rp->swallow_params.min.w = w;
4025 rp->swallow_params.min.h = h;
4026 rp->swallow_params.max.w = w;
4027 rp->swallow_params.max.h = h;
4028 }
4029 {
4030 Evas_Coord w1, h1, w2, h2, aw, ah;
4031 Evas_Aspect_Control am;
4032
4033 evas_object_size_hint_min_get(rp->swallowed_object, &w1, &h1);
4034 evas_object_size_hint_max_get(rp->swallowed_object, &w2, &h2);
4035 evas_object_size_hint_aspect_get(rp->swallowed_object, &am, &aw, &ah);
4036 rp->swallow_params.min.w = w1;
4037 rp->swallow_params.min.h = h1;
4038 if (w2 > 0) rp->swallow_params.max.w = w2;
4039 if (h2 > 0) rp->swallow_params.max.h = h2;
4040 switch (am)
4041 {
4042 case EVAS_ASPECT_CONTROL_NONE:
4043 rp->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_NONE;
4044 break;
4045 case EVAS_ASPECT_CONTROL_NEITHER:
4046 rp->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_NEITHER;
4047 break;
4048 case EVAS_ASPECT_CONTROL_HORIZONTAL:
4049 rp->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_HORIZONTAL;
4050 break;
4051 case EVAS_ASPECT_CONTROL_VERTICAL:
4052 rp->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_VERTICAL;
4053 break;
4054 case EVAS_ASPECT_CONTROL_BOTH:
4055 rp->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_BOTH;
4056 break;
4057 default:
4058 break;
4059 }
4060 rp->swallow_params.aspect.w = aw;
4061 rp->swallow_params.aspect.h = ah;
4062 evas_object_data_set(rp->swallowed_object, "\377 edje.swallowing_part", rp);
4063 }
4064
4065#ifdef EDJE_CALC_CACHE
4066 rp->invalidate = 1;
4067#endif
4068}
4069
4070void
4071_edje_object_part_swallow_changed_hints_cb(void *data, __UNUSED__ Evas *e, __UNUSED__ Evas_Object *obj, __UNUSED__ void *event_info)
4072{
4073 Edje_Real_Part *rp;
4074
4075 rp = data;
4076 _edje_real_part_swallow_hints_update(rp);
4077 rp->edje->dirty = 1;
4078 _edje_recalc(rp->edje);
4079 return;
4080}
4081
4082void
4083_edje_real_part_swallow(Edje_Real_Part *rp,
4084 Evas_Object *obj_swallow,
4085 Eina_Bool hints_update)
4086{
4087 if (rp->swallowed_object)
4088 {
4089 if (rp->swallowed_object != obj_swallow)
4090 {
4091 _edje_real_part_swallow_clear(rp);
4092 rp->swallowed_object = NULL;
4093 }
4094 else
4095 {
4096 if (hints_update)
4097 _edje_real_part_swallow_hints_update(rp);
4098 rp->edje->dirty = 1;
4099 _edje_recalc(rp->edje);
4100 return;
4101 }
4102 }
4103#ifdef EDJE_CALC_CACHE
4104 rp->invalidate = 1;
4105#endif
4106 if (!obj_swallow) return;
4107 rp->swallowed_object = obj_swallow;
4108 evas_object_smart_member_add(rp->swallowed_object, rp->edje->obj);
4109 if (rp->clip_to)
4110 evas_object_clip_set(rp->swallowed_object, rp->clip_to->object);
4111 else evas_object_clip_set(rp->swallowed_object, rp->edje->base.clipper);
4112 evas_object_stack_above(rp->swallowed_object, rp->object);
4113 evas_object_event_callback_add(rp->swallowed_object,
4114 EVAS_CALLBACK_DEL,
4115 _edje_object_part_swallow_free_cb,
4116 rp->edje->obj);
4117 evas_object_event_callback_add(rp->swallowed_object,
4118 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
4119 _edje_object_part_swallow_changed_hints_cb,
4120 rp);
4121
4122 if (hints_update)
4123 _edje_real_part_swallow_hints_update(rp);
4124
4125 if (rp->part->mouse_events)
4126 {
4127 _edje_callbacks_add(obj_swallow, rp->edje, rp);
4128 if (rp->part->repeat_events)
4129 evas_object_repeat_events_set(obj_swallow, 1);
4130 if (rp->part->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB)
4131 evas_object_pointer_mode_set(obj_swallow, rp->part->pointer_mode);
4132 evas_object_pass_events_set(obj_swallow, 0);
4133 }
4134 else
4135 evas_object_pass_events_set(obj_swallow, 1);
4136 _edje_callbacks_focus_add(rp->swallowed_object, rp->edje, rp);
4137
4138 if (rp->part->precise_is_inside)
4139 evas_object_precise_is_inside_set(obj_swallow, 1);
4140
4141 rp->edje->dirty = 1;
4142 _edje_recalc(rp->edje);
4143}
4144
4145void
4146_edje_real_part_swallow_clear(Edje_Real_Part *rp)
4147{
4148 evas_object_smart_member_del(rp->swallowed_object);
4149 evas_object_event_callback_del_full(rp->swallowed_object,
4150 EVAS_CALLBACK_FREE,
4151 _edje_object_part_swallow_free_cb,
4152 rp->edje->obj);
4153 evas_object_event_callback_del_full(rp->swallowed_object,
4154 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
4155 _edje_object_part_swallow_changed_hints_cb,
4156 rp);
4157 evas_object_clip_unset(rp->swallowed_object);
4158 evas_object_data_del(rp->swallowed_object, "\377 edje.swallowing_part");
4159 if (rp->part->mouse_events)
4160 _edje_callbacks_del(rp->swallowed_object, rp->edje);
4161 _edje_callbacks_focus_del(rp->swallowed_object, rp->edje);
4162}
4163
4164static void
4165_edje_object_preload(Edje *ed)
4166{
4167 ed->preload_count--;
4168 if (!ed->preload_count)
4169 _edje_emit(ed, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE);
4170}
4171
4172static void
4173_edje_object_image_preload_cb(void *data, __UNUSED__ Evas *e, Evas_Object *obj, __UNUSED__ void *event_info)
4174{
4175 Edje *ed = data;
4176
4177 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
4178 _edje_object_preload(ed);
4179}
4180
4181static void
4182_edje_object_signal_preload_cb(void *data, Evas_Object *obj, __UNUSED__ const char *emission, __UNUSED__ const char *source)
4183{
4184 Edje *ed = data;
4185
4186 edje_object_signal_callback_del(obj, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE, _edje_object_signal_preload_cb);
4187 _edje_object_preload(ed);
4188}
4189
4190/**
4191 * @internal
4192 *
4193 * for edje_cc
4194 */
4195EAPI void
4196_edje_program_remove(Edje_Part_Collection *edc, Edje_Program *p)
4197{
4198 Edje_Program ***array;
4199 unsigned int *count;
4200 unsigned int i;
4201
4202 if (!p->signal && !p->source)
4203 {
4204 array = &edc->programs.nocmp;
4205 count = &edc->programs.nocmp_count;
4206 }
4207 else if (p->signal && !strpbrk(p->signal, "*?[\\")
4208 && p->source && !strpbrk(p->source, "*?[\\"))
4209 {
4210 array = &edc->programs.strcmp;
4211 count = &edc->programs.strcmp_count;
4212 }
4213 else if (p->signal && edje_program_is_strncmp(p->signal)
4214 && p->source && edje_program_is_strncmp(p->source))
4215 {
4216 array = &edc->programs.strncmp;
4217 count = &edc->programs.strncmp_count;
4218 }
4219 else if (p->signal && edje_program_is_strrncmp(p->signal)
4220 && p->source && edje_program_is_strrncmp(p->source))
4221 {
4222 array = &edc->programs.strrncmp;
4223 count = &edc->programs.strrncmp_count;
4224 }
4225 else
4226 {
4227 array = &edc->programs.fnmatch;
4228 count = &edc->programs.fnmatch_count;
4229 }
4230
4231 for (i = 0; i < *count; ++i)
4232 if ((*array)[i] == p)
4233 {
4234 memmove(*array + i, *array + i + 1, sizeof (Edje_Program *) * (*count - i -1));
4235 (*count)--;
4236 break;
4237 }
4238}
4239
4240/**
4241 * @internal
4242 *
4243 * for edje_cc
4244 */
4245EAPI void
4246_edje_program_insert(Edje_Part_Collection *edc, Edje_Program *p)
4247{
4248 Edje_Program ***array;
4249 unsigned int *count;
4250
4251 if (!p->signal && !p->source)
4252 {
4253 array = &edc->programs.nocmp;
4254 count = &edc->programs.nocmp_count;
4255 }
4256 else if (p->signal && !strpbrk(p->signal, "*?[\\")
4257 && p->source && !strpbrk(p->source, "*?[\\"))
4258 {
4259 array = &edc->programs.strcmp;
4260 count = &edc->programs.strcmp_count;
4261 }
4262 else if (p->signal && edje_program_is_strncmp(p->signal)
4263 && p->source && edje_program_is_strncmp(p->source))
4264 {
4265 array = &edc->programs.strncmp;
4266 count = &edc->programs.strncmp_count;
4267 }
4268 else if (p->signal && edje_program_is_strrncmp(p->signal)
4269 && p->source && edje_program_is_strrncmp(p->source))
4270 {
4271 array = &edc->programs.strrncmp;
4272 count = &edc->programs.strrncmp_count;
4273 }
4274 else
4275 {
4276 array = &edc->programs.fnmatch;
4277 count = &edc->programs.fnmatch_count;
4278 }
4279
4280 *array = realloc(*array, sizeof (Edje_Program *) * (*count + 1));
4281 (*array)[(*count)++] = p;
4282}
4283
4284const char *
4285edje_string_get(const Edje_String *es)
4286{
4287 /* FIXME: Handle localization here */
4288 if (!es) return NULL;
4289 return es->str;
4290}
4291
4292const char *
4293edje_string_id_get(const Edje_String *es)
4294{
4295 /* FIXME: Handle localization here */
4296 if (!es) return NULL;
4297 return es->str;
4298}
4299
4300static void
4301_cb_subobj_del(void *data, __UNUSED__ Evas *e, Evas_Object *obj, __UNUSED__ void *event_info)
4302{
4303 Edje *ed = data;
4304 ed->subobjs = eina_list_remove(ed->subobjs, obj);
4305 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
4306 _cb_subobj_del, ed);
4307}
4308
4309void
4310_edje_subobj_register(Edje *ed, Evas_Object *ob)
4311{
4312 ed->subobjs = eina_list_append(ed->subobjs, ob);
4313 evas_object_event_callback_add(ob, EVAS_CALLBACK_DEL,
4314 _cb_subobj_del, ed);
4315}
4316
4317/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/