1 #include "edje_private.h"
2
3 #include "../evas/canvas/evas_box_eo.h"
4 #include "../evas/canvas/evas_line_eo.h"
5 #include "../evas/canvas/evas_text_eo.h"
6
7 //In implementations that gets properties for user-created edje,
8 //edje calculation should be performed regardless of the size of edje.
9 #define EDJE_RECALC_DO(ed) \
10 do { \
11 Eina_Bool calc_flag = EINA_FALSE; \
12 if (!ed->has_size) \
13 { \
14 ed->has_size = EINA_TRUE; \
15 calc_flag = EINA_TRUE; \
16 } \
17 _edje_recalc_do(ed); \
18 if (calc_flag) ed->has_size = EINA_FALSE; \
19 } while (0)
20
21 typedef struct _Edje_Box_Layout Edje_Box_Layout;
22 struct _Edje_Box_Layout
23 {
24 EINA_RBTREE;
25 Evas_Object_Box_Layout func;
26 void *(*layout_data_get)(void *);
27 void (*layout_data_free)(void *);
28 void *data;
29 void (*free_data)(void *);
30 char name[];
31 };
32
33 static Eina_Hash *_edje_color_class_hash = NULL;
34 static Eina_Hash *_edje_text_class_hash = NULL;
35 static Eina_Hash *_edje_size_class_hash = NULL;
36
37 Efl_Observable *_edje_color_class_member = NULL;
38 Efl_Observable *_edje_text_class_member = NULL;
39 Efl_Observable *_edje_size_class_member = NULL;
40
41 static Eina_Rbtree *_edje_box_layout_registry = NULL;
42
43 char *_edje_fontset_append = NULL;
44 char *_edje_fontset_append_escaped = NULL;
45 FLOAT_T _edje_scale = ZERO;
46 Eina_Bool _edje_password_show_last = EINA_FALSE;
47 double _edje_password_show_last_timeout = 0;
48 int _edje_util_freeze_val = 0;
49 int _edje_util_freeze_calc_count = 0;
50 Eina_List *_edje_util_freeze_calc_list = NULL;
51
52 const char *_edje_language = NULL;
53 const char *_edje_cache_path = NULL;
54
55 typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
56 struct _Edje_List_Foreach_Data
57 {
58 Eina_List *list;
59 };
60
61 typedef struct _Edje_Refcount Edje_Refcount;
62 struct _Edje_Refcount
63 {
64 EINA_REFCOUNT;
65
66 Edje *ed;
67 };
68
69 static Eina_Bool _edje_color_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
70 static Eina_Bool _edje_text_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
71 static Eina_Bool _edje_size_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
72 static void _edje_object_image_preload_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
73 static void _edje_object_signal_preload_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
74 static void _edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_UNUSED, void *einfo EINA_UNUSED);
75 static void _edje_child_remove(Edje *ed, Edje_Real_Part *rp, Evas_Object *child);
76
77 Edje_Real_Part *_edje_real_part_recursive_get_helper(Edje **ed, char **path);
78
79 static void
_edje_user_definition_free_internal(Edje_User_Defined * eud)80 _edje_user_definition_free_internal(Edje_User_Defined *eud)
81 {
82 Evas_Object *child = NULL;
83 switch (eud->type)
84 {
85 case EDJE_USER_SWALLOW:
86 child = eud->u.swallow.child;
87 break;
88
89 case EDJE_USER_BOX_PACK:
90 child = eud->u.box.child;
91 break;
92
93 case EDJE_USER_TABLE_PACK:
94 child = eud->u.table.child;
95 break;
96
97 default: break;
98 }
99 if (child) evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
100 eina_stringshare_del(eud->part);
101 free(eud);
102 }
103
104 static void
_edje_user_definition_list_free_internal(Eina_List * l)105 _edje_user_definition_list_free_internal(Eina_List *l)
106 {
107 Edje_User_Defined *eud;
108 EINA_LIST_FREE(l, eud)
109 _edje_user_definition_free_internal(eud);
110 }
111
112 static Edje_User_Defined *
_edje_user_definition_new(Edje_User_Defined_Type type,const char * part,Edje * ed)113 _edje_user_definition_new(Edje_User_Defined_Type type, const char *part, Edje *ed)
114 {
115 Edje_User_Defined *eud;
116
117 if (!ed->user_defined)
118 ed->user_defined = eina_hash_string_superfast_new((Eina_Free_Cb)_edje_user_definition_list_free_internal);
119 EINA_SAFETY_ON_NULL_RETURN_VAL(ed->user_defined, NULL);
120
121 eud = malloc(sizeof (Edje_User_Defined));
122 if (!eud) return NULL;
123
124 eud->type = type;
125 eud->part = eina_stringshare_add(part);
126 eud->ed = ed;
127 eina_hash_list_direct_append(ed->user_defined, eud->part, eud);
128
129 return eud;
130 }
131
132 void
_edje_user_definition_free(Edje_User_Defined * eud)133 _edje_user_definition_free(Edje_User_Defined *eud)
134 {
135 Edje_Real_Part *rp;
136
137 switch (eud->type)
138 {
139 case EDJE_USER_SWALLOW:
140 rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
141 if (rp)
142 {
143 _edje_real_part_swallow_clear(eud->ed, rp);
144 if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
145 (rp->typedata.swallow))
146 {
147 rp->typedata.swallow->swallowed_object = NULL;
148 rp->typedata.swallow->swallow_params.min.w = 0;
149 rp->typedata.swallow->swallow_params.min.h = 0;
150 rp->typedata.swallow->swallow_params.max.w = 0;
151 rp->typedata.swallow->swallow_params.max.h = 0;
152 }
153 eud->ed->dirty = EINA_TRUE;
154 eud->ed->recalc_call = EINA_TRUE;
155 #ifdef EDJE_CALC_CACHE
156 rp->invalidate = EINA_TRUE;
157 #endif
158 /* this seems to be as unnecessary as the one in part_unswallow()
159 * cedric, 1 February 2016
160 */
161 // _edje_recalc_do(eud->ed);
162 }
163 break;
164
165 case EDJE_USER_BOX_PACK:
166 rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
167 if (rp) _edje_child_remove(eud->ed, rp, eud->u.box.child);
168 break;
169
170 case EDJE_USER_TABLE_PACK:
171 rp = _edje_real_part_recursive_get(&eud->ed, eud->part);
172 if (rp) _edje_child_remove(eud->ed, rp, eud->u.table.child);
173 break;
174
175 case EDJE_USER_TEXT_STYLE:
176 {
177 Edje_Part_Text_Prop *prop;
178 EINA_LIST_FREE(eud->u.text_style.props, prop)
179 {
180 free(prop);
181 }
182 break;
183 }
184
185 case EDJE_USER_STRING:
186 case EDJE_USER_DRAG_STEP:
187 case EDJE_USER_DRAG_PAGE:
188 case EDJE_USER_DRAG_VALUE:
189 case EDJE_USER_DRAG_SIZE:
190 case EDJE_USER_TEXT_EXPAND:
191 break;
192 }
193
194 /* edje may be destructing */
195 if (eud->ed->user_defined) eina_hash_list_remove(eud->ed->user_defined, eud->part, eud);
196 _edje_user_definition_free_internal(eud);
197 }
198
199 static void
_edje_user_def_del_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * child EINA_UNUSED,void * einfo EINA_UNUSED)200 _edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_UNUSED, void *einfo EINA_UNUSED)
201 {
202 Edje_User_Defined *eud = data;
203
204 _edje_user_definition_free(eud);
205 }
206
207 /************************** API Routines **************************/
208
209 #define FASTFREEZE 1
210
211 EAPI void
edje_freeze(void)212 edje_freeze(void)
213 {
214 #ifdef FASTFREEZE
215 _edje_util_freeze_val++;
216 #else
217 // FIXME: could just have a global freeze instead of per object
218 // above i tried.. but this broke some things. notable e17's menus. why?
219 Edje *ed;
220
221 EINA_INLIST_FOREACH(_edje_edjes, ed) edje_object_freeze(ed->obj);
222 #endif
223 }
224
225 #ifdef FASTFREEZE
226 static void
_edje_util_thaw_edje(Edje * ed)227 _edje_util_thaw_edje(Edje *ed)
228 {
229 unsigned short i;
230
231 for (i = 0; i < ed->table_parts_size; i++)
232 {
233 Edje_Real_Part *rp;
234
235 rp = ed->table_parts[i];
236 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
237 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
238 (rp->typedata.swallow)) &&
239 (rp->typedata.swallow->swallowed_object))
240 {
241 Edje *ed2;
242
243 ed2 = _edje_fetch(rp->typedata.swallow->swallowed_object);
244 if (ed2) _edje_util_thaw_edje(ed2);
245 }
246 }
247 if ((ed->recalc) && (ed->freeze == 0)) _edje_recalc_do(ed);
248 }
249
250 #endif
251
252 void
_edje_language_signal_emit(Edje * ed,Evas_Object * obj,char * signal)253 _edje_language_signal_emit(Edje *ed, Evas_Object *obj, char *signal)
254 {
255 unsigned short i;
256
257 for (i = 0; i < ed->table_parts_size; i++)
258 {
259 Edje_Real_Part *rp = ed->table_parts[i];
260
261 if (rp->part->type == EDJE_PART_TYPE_TEXT ||
262 rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
263 {
264 Edje_Part_Description_Text *text;
265
266 text = (Edje_Part_Description_Text *)rp->param1.description;
267 if (text->text.text.translated)
268 text->text.text.translated = NULL;
269
270 if (rp->param2)
271 {
272 text = (Edje_Part_Description_Text *)rp->param2->description;
273 if (text->text.text.translated)
274 text->text.text.translated = NULL;
275 }
276
277 if (rp->custom)
278 {
279 text = (Edje_Part_Description_Text *)rp->custom->description;
280 if (text->text.text.translated)
281 text->text.text.translated = NULL;
282 }
283 }
284 }
285 edje_object_signal_emit(obj, signal, "edje");
286 edje_object_calc_force(obj);
287 }
288
289 EOLIAN void
_efl_canvas_layout_efl_ui_i18n_language_set(Eo * obj,Edje * ed,const char * locale)290 _efl_canvas_layout_efl_ui_i18n_language_set(Eo *obj, Edje *ed, const char *locale)
291 {
292 const char *lookup;
293 char *signal;
294 size_t length;
295
296 if (!locale) return;
297 lookup = strstr(locale, ".");
298 length = lookup ? (size_t)(lookup - locale) : strlen(locale);
299
300 eina_stringshare_replace_length(&ed->language, locale, length);
301
302 signal = alloca(length + 15);
303 if (ed->language)
304 snprintf(signal, length + 15, "edje,language,%s", ed->language);
305 else
306 snprintf(signal, length + 15, "edje,language,%s", "none");
307
308 _edje_language_signal_emit(ed, obj, signal);
309 }
310
311 EOLIAN const char *
_efl_canvas_layout_efl_ui_i18n_language_get(const Eo * obj EINA_UNUSED,Edje * ed)312 _efl_canvas_layout_efl_ui_i18n_language_get(const Eo *obj EINA_UNUSED, Edje *ed)
313 {
314 if (!ed->language)
315 return _edje_language;
316
317 return ed->language;
318 }
319
320 EAPI void
edje_language_set(const char * locale)321 edje_language_set(const char *locale)
322 {
323 Edje *ed;
324 const char *lookup;
325 char *signal;
326 char *loc;
327 int length;
328
329 if (!locale) return;
330 lookup = strstr(locale, ".");
331 length = lookup ? lookup - locale : (int)strlen(locale);
332 loc = alloca(length + 1);
333 memcpy(loc, locale, length);
334 loc[length] = '\0';
335
336 eina_stringshare_replace(&_edje_language, loc);
337
338 signal = alloca(length + 15);
339 snprintf(signal, length + 15, "edje,language,%s", loc);
340
341 EINA_INLIST_FOREACH(_edje_edjes, ed)
342 {
343 if (ed->language) continue;
344 _edje_language_signal_emit(ed, ed->obj, signal);
345 }
346 }
347
348 EAPI void
edje_thaw(void)349 edje_thaw(void)
350 {
351 #ifdef FASTFREEZE
352 if (!_edje_util_freeze_val) return;
353 _edje_util_freeze_val--;
354 if ((_edje_util_freeze_val == 0) && (_edje_util_freeze_calc_count > 0))
355 {
356 Edje *ed;
357
358 _edje_util_freeze_calc_count = 0;
359 EINA_LIST_FREE(_edje_util_freeze_calc_list, ed)
360 {
361 _edje_util_thaw_edje(ed);
362 ed->freeze_calc = EINA_FALSE;
363 }
364 }
365 #else
366 Edje *ed;
367
368 EINA_INLIST_FOREACH(_edje_edjes, ed) edje_object_thaw(ed->obj);
369 #endif
370 }
371
372 EAPI void
edje_fontset_append_set(const char * fonts)373 edje_fontset_append_set(const char *fonts)
374 {
375 if (_edje_fontset_append)
376 {
377 free(_edje_fontset_append);
378 free(_edje_fontset_append_escaped);
379 }
380 _edje_fontset_append = fonts ? strdup(fonts) : NULL;
381 _edje_fontset_append_escaped = fonts ? eina_str_escape(fonts) : NULL;
382 }
383
384 EAPI const char *
edje_fontset_append_get(void)385 edje_fontset_append_get(void)
386 {
387 return _edje_fontset_append;
388 }
389
390 EAPI void
edje_scale_set(double scale)391 edje_scale_set(double scale)
392 {
393 Edje *ed;
394
395 if (EQ(_edje_scale, FROM_DOUBLE(scale))) return;
396 _edje_scale = FROM_DOUBLE(scale);
397 EINA_INLIST_FOREACH(_edje_edjes, ed) edje_object_calc_force(ed->obj);
398 }
399
400 EAPI double
edje_scale_get(void)401 edje_scale_get(void)
402 {
403 return TO_DOUBLE(_edje_scale);
404 }
405
406 EAPI void
edje_password_show_last_set(Eina_Bool password_show_last)407 edje_password_show_last_set(Eina_Bool password_show_last)
408 {
409 if (_edje_password_show_last == password_show_last) return;
410 _edje_password_show_last = password_show_last;
411 }
412
413 EAPI void
edje_password_show_last_timeout_set(double password_show_last_timeout)414 edje_password_show_last_timeout_set(double password_show_last_timeout)
415 {
416 if (EINA_DBL_EQ(_edje_password_show_last_timeout, password_show_last_timeout)) return;
417 _edje_password_show_last_timeout = password_show_last_timeout;
418 }
419
420 EOLIAN void
_efl_canvas_layout_efl_gfx_entity_scale_set(Eo * obj EINA_UNUSED,Edje * ed,double scale)421 _efl_canvas_layout_efl_gfx_entity_scale_set(Eo *obj EINA_UNUSED, Edje *ed, double scale)
422 {
423 Edje *ged;
424 Evas_Object *o;
425 Eina_List *l;
426 unsigned short i;
427
428 if (EQ(ed->scale, FROM_DOUBLE(scale))) return;
429 ed->scale = FROM_DOUBLE(scale);
430 EINA_LIST_FOREACH(ed->groups, l, ged)
431 edje_object_scale_set(ged->obj, scale);
432 for (i = 0; i < ed->table_parts_size; i++)
433 {
434 Edje_Real_Part *ep;
435 ep = ed->table_parts[i];
436 if ((ep->part->type == EDJE_PART_TYPE_BOX) ||
437 (ep->part->type == EDJE_PART_TYPE_TABLE))
438 {
439 EINA_LIST_FOREACH(ep->typedata.container->items, l, o)
440 edje_object_scale_set(o, scale);
441 }
442 }
443 _edje_recalc(ed);
444 }
445
446 EOLIAN double
_efl_canvas_layout_efl_gfx_entity_scale_get(const Eo * obj EINA_UNUSED,Edje * ed)447 _efl_canvas_layout_efl_gfx_entity_scale_get(const Eo *obj EINA_UNUSED, Edje *ed)
448 {
449 return TO_DOUBLE(ed->scale);
450 }
451
452 EAPI double
edje_object_base_scale_get(const Evas_Object * obj)453 edje_object_base_scale_get(const Evas_Object *obj)
454 {
455 Edje *ed;
456
457 ed = _edje_fetch(obj);
458 if (!ed || !ed->file) return 1.0;
459 return TO_DOUBLE(ed->file->base_scale);
460 }
461
462 EOLIAN Eina_Bool
_efl_canvas_layout_efl_ui_i18n_mirrored_get(const Eo * obj EINA_UNUSED,Edje * ed)463 _efl_canvas_layout_efl_ui_i18n_mirrored_get(const Eo *obj EINA_UNUSED, Edje *ed)
464 {
465 return ed->is_rtl;
466 }
467
468 void
_edje_object_orientation_inform(Evas_Object * obj)469 _edje_object_orientation_inform(Evas_Object *obj)
470 {
471 if (!obj) return;
472 if (edje_object_mirrored_get(obj))
473 edje_object_signal_emit(obj, "edje,state,rtl", "edje");
474 else
475 edje_object_signal_emit(obj, "edje,state,ltr", "edje");
476 }
477
478 EOLIAN void
_efl_canvas_layout_efl_ui_i18n_mirrored_set(Eo * obj,Edje * ed,Eina_Bool rtl)479 _efl_canvas_layout_efl_ui_i18n_mirrored_set(Eo *obj, Edje *ed, Eina_Bool rtl)
480 {
481 unsigned short i;
482
483 if (ed->is_rtl == rtl) return;
484
485 ed->is_rtl = rtl;
486
487 for (i = 0; i < ed->table_parts_size; i++)
488 {
489 Edje_Real_Part *ep;
490 const char *s;
491 double v;
492
493 ep = ed->table_parts[i];
494 s = ep->param1.description->state.name,
495 v = ep->param1.description->state.value;
496 _edje_part_description_apply(ed, ep, s, v, NULL, 0.0);
497 ep->chosen_description = ep->param1.description;
498 }
499 if (!ed->freeze) _edje_recalc_do(ed);
500
501 _edje_object_orientation_inform(obj);
502
503 return;
504 }
505
506 EOLIAN const char *
_efl_canvas_layout_efl_layout_group_group_data_get(const Eo * obj EINA_UNUSED,Edje * ed,const char * key)507 _efl_canvas_layout_efl_layout_group_group_data_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *key)
508 {
509 if (!key) return NULL;
510 if (!ed->collection) return NULL;
511 if (!ed->collection->data) return NULL;
512
513 return edje_string_get(eina_hash_find(ed->collection->data, key));
514 }
515
516 EOLIAN int
_efl_canvas_layout_efl_layout_calc_calc_freeze(Eo * obj EINA_UNUSED,Edje * ed)517 _efl_canvas_layout_efl_layout_calc_calc_freeze(Eo *obj EINA_UNUSED, Edje *ed)
518 {
519 unsigned short i;
520
521 for (i = 0; i < ed->table_parts_size; i++)
522 {
523 Edje_Real_Part *rp;
524 rp = ed->table_parts[i];
525 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
526 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
527 (rp->typedata.swallow)) &&
528 (rp->typedata.swallow->swallowed_object))
529 edje_object_freeze(rp->typedata.swallow->swallowed_object);
530 }
531 return _edje_util_freeze(ed);
532 }
533
534 EOLIAN int
_efl_canvas_layout_efl_layout_calc_calc_thaw(Eo * obj EINA_UNUSED,Edje * ed)535 _efl_canvas_layout_efl_layout_calc_calc_thaw(Eo *obj EINA_UNUSED, Edje *ed)
536 {
537 unsigned short i;
538
539 for (i = 0; i < ed->table_parts_size; i++)
540 {
541 Edje_Real_Part *rp;
542
543 rp = ed->table_parts[i];
544 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
545 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
546 (rp->typedata.swallow)) &&
547 (rp->typedata.swallow->swallowed_object))
548 edje_object_thaw(rp->typedata.swallow->swallowed_object);
549 }
550 return _edje_util_thaw(ed);
551 }
552
553 static Eina_Bool
_edje_color_class_set_internal(Eina_Hash * hash,const char * color_class,Efl_Gfx_Color_Class_Layer layer,int r,int g,int b,int a,Eina_Bool * need_update)554 _edje_color_class_set_internal(Eina_Hash *hash, const char *color_class, Efl_Gfx_Color_Class_Layer layer, int r, int g, int b, int a, Eina_Bool *need_update)
555 {
556 Edje_Color_Class *cc;
557
558 if (!color_class)
559 return EINA_FALSE;
560
561 if (r < 0) r = 0;
562 else if (r > 255)
563 r = 255;
564 if (g < 0) g = 0;
565 else if (g > 255)
566 g = 255;
567 if (b < 0) b = 0;
568 else if (b > 255)
569 b = 255;
570 if (a < 0) a = 0;
571 else if (a > 255)
572 a = 255;
573
574 cc = eina_hash_find(hash, color_class);
575 if (cc)
576 {
577 switch (layer)
578 {
579 case EFL_GFX_COLOR_CLASS_LAYER_NORMAL:
580 if ((cc->r == r) && (cc->g == g) &&
581 (cc->b == b) && (cc->a == a))
582 {
583 *need_update = EINA_FALSE;
584 return EINA_TRUE;
585 }
586 break;
587
588 case EFL_GFX_COLOR_CLASS_LAYER_OUTLINE:
589 if ((cc->r2 == r) && (cc->g2 == g) &&
590 (cc->b2 == b) && (cc->a2 == a))
591 {
592 *need_update = EINA_FALSE;
593 return EINA_TRUE;
594 }
595 break;
596
597 case EFL_GFX_COLOR_CLASS_LAYER_SHADOW:
598 if ((cc->r3 == r) && (cc->g3 == g) &&
599 (cc->b3 == b) && (cc->a3 == a))
600 {
601 *need_update = EINA_FALSE;
602 return EINA_TRUE;
603 }
604 break;
605
606 default:
607 return EINA_FALSE;
608 }
609 }
610 else
611 {
612 cc = calloc(1, sizeof(Edje_Color_Class));
613 if (!cc) return EINA_FALSE;
614
615 cc->name = eina_stringshare_add(color_class);
616 if (!cc->name)
617 {
618 free(cc);
619 return EINA_FALSE;
620 }
621
622 eina_hash_direct_add(hash, cc->name, cc);
623 }
624
625 switch (layer)
626 {
627 case EFL_GFX_COLOR_CLASS_LAYER_NORMAL:
628 cc->r = r;
629 cc->g = g;
630 cc->b = b;
631 cc->a = a;
632 break;
633
634 case EFL_GFX_COLOR_CLASS_LAYER_OUTLINE:
635 cc->r2 = r;
636 cc->g2 = g;
637 cc->b2 = b;
638 cc->a2 = a;
639 break;
640
641 case EFL_GFX_COLOR_CLASS_LAYER_SHADOW:
642 cc->r3 = r;
643 cc->g3 = g;
644 cc->b3 = b;
645 cc->a3 = a;
646 break;
647 }
648
649 *need_update = EINA_TRUE;
650
651 return EINA_TRUE;
652 }
653
654 static Eina_Bool
_edje_color_class_get_internal(Edje_Color_Class * cc,Efl_Gfx_Color_Class_Layer layer,int * r,int * g,int * b,int * a)655 _edje_color_class_get_internal(Edje_Color_Class *cc, Efl_Gfx_Color_Class_Layer layer, int *r, int *g, int *b, int *a)
656 {
657 if (cc)
658 {
659 switch (layer)
660 {
661 case EFL_GFX_COLOR_CLASS_LAYER_NORMAL:
662 if (r) *r = cc->r;
663 if (g) *g = cc->g;
664 if (b) *b = cc->b;
665 if (a) *a = cc->a;
666 break;
667
668 case EFL_GFX_COLOR_CLASS_LAYER_OUTLINE:
669 if (r) *r = cc->r2;
670 if (g) *g = cc->g2;
671 if (b) *b = cc->b2;
672 if (a) *a = cc->a2;
673 break;
674
675 case EFL_GFX_COLOR_CLASS_LAYER_SHADOW:
676 if (r) *r = cc->r3;
677 if (g) *g = cc->g3;
678 if (b) *b = cc->b3;
679 if (a) *a = cc->a3;
680 break;
681 }
682 return EINA_TRUE;
683 }
684 else
685 {
686 if (r) *r = 0;
687 if (g) *g = 0;
688 if (b) *b = 0;
689 if (a) *a = 0;
690
691 return EINA_FALSE;
692 }
693 }
694
695 EAPI Eina_Bool
edje_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)696 edje_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)
697 {
698 Eina_Bool result = EINA_TRUE;
699 Eina_Bool normal = EINA_FALSE , outline = EINA_FALSE , shadow = EINA_FALSE;
700
701 if (!_edje_color_class_hash)
702 _edje_color_class_hash = eina_hash_string_superfast_new(NULL);
703
704 result &= _edje_color_class_set_internal(_edje_color_class_hash, color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a, &normal);
705 result &= _edje_color_class_set_internal(_edje_color_class_hash, color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2, &outline);
706 result &= _edje_color_class_set_internal(_edje_color_class_hash, color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3, &shadow);
707
708 // either of them changes then request an update.
709 if (result && (normal || outline || shadow))
710 efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,set");
711
712 return result;
713 }
714
715 EOLIAN Eina_Bool
_edje_global_efl_gfx_color_class_color_class_set(Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * color_class,Efl_Gfx_Color_Class_Layer layer,int r,int g,int b,int a)716 _edje_global_efl_gfx_color_class_color_class_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
717 const char *color_class, Efl_Gfx_Color_Class_Layer layer, int r, int g, int b, int a)
718 {
719 Eina_Bool int_ret;
720 Eina_Bool need_update = EINA_FALSE;
721
722 if (!_edje_color_class_hash)
723 _edje_color_class_hash = eina_hash_string_superfast_new(NULL);
724
725 int_ret = _edje_color_class_set_internal(_edje_color_class_hash, color_class, layer, r, g, b, a, &need_update);
726
727 if ((int_ret) && (need_update))
728 efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,set");
729
730 return int_ret;
731 }
732
733 EAPI Eina_Bool
edje_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)734 edje_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)
735 {
736 Eina_Bool int_ret = EINA_TRUE;
737
738 int_ret &= efl_gfx_color_class_get(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a);
739 int_ret &= efl_gfx_color_class_get(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2);
740 int_ret &= efl_gfx_color_class_get(_edje_global(), color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3);
741
742 return int_ret;
743 }
744
745 EOLIAN Eina_Bool
_edje_global_efl_gfx_color_class_color_class_get(const Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * color_class,Efl_Gfx_Color_Class_Layer layer,int * r,int * g,int * b,int * a)746 _edje_global_efl_gfx_color_class_color_class_get(const Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
747 const char *color_class, Efl_Gfx_Color_Class_Layer layer, int *r, int *g, int *b, int *a)
748 {
749 Edje_Color_Class *cc;
750
751 if (!color_class)
752 cc = NULL;
753 else
754 cc = eina_hash_find(_edje_color_class_hash, color_class);
755
756 return _edje_color_class_get_internal(cc, layer, r, g, b, a);
757 }
758
759 EAPI void
edje_color_class_del(const char * color_class)760 edje_color_class_del(const char *color_class)
761 {
762 efl_gfx_color_class_del(_edje_global(), color_class);
763 }
764
765 EOLIAN void
_edje_global_efl_gfx_color_class_color_class_del(Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * color_class)766 _edje_global_efl_gfx_color_class_color_class_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *color_class)
767 {
768 Edje_Color_Class *cc;
769
770 if (!color_class) return;
771
772 cc = eina_hash_find(_edje_color_class_hash, color_class);
773 if (!cc) return;
774
775 eina_hash_del(_edje_color_class_hash, color_class, cc);
776 eina_stringshare_del(cc->name);
777 free(cc);
778
779 efl_observable_observers_update(_edje_color_class_member, color_class, "color_class,del");
780 }
781
782 Eina_List *
edje_color_class_list(void)783 edje_color_class_list(void)
784 {
785 Edje_List_Foreach_Data fdata;
786
787 if (!_edje_color_class_hash) return NULL;
788 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
789 eina_hash_foreach(_edje_color_class_hash,
790 _edje_color_class_list_foreach, &fdata);
791
792 return fdata.list;
793 }
794
795 typedef struct _Edje_Active_Color_Class_Iterator Edje_Active_Color_Class_Iterator;
796 struct _Edje_Active_Color_Class_Iterator
797 {
798 Eina_Iterator iterator;
799
800 Edje_Color_Class cc;
801
802 Eina_Iterator *classes;
803 };
804
805 static Eina_Bool
_edje_color_class_active_iterator_next(Eina_Iterator * it,void ** data)806 _edje_color_class_active_iterator_next(Eina_Iterator *it, void **data)
807 {
808 Edje_Active_Color_Class_Iterator *et = (void *)it;
809 Efl_Observable_Tuple *tuple = NULL;
810 Efl_Observer *o;
811 Edje *ed;
812 Edje_Color_Class *cc = NULL;
813
814 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
815 if (!tuple) return EINA_FALSE;
816
817 if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
818
819 ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
820 if (!ed) return EINA_FALSE;
821
822 /*
823 We actually need to ask on an object to get the correct value.
824 It is being assumed that the color key are the same for all object here.
825 This can some times not be the case, but for now we should be fine.
826 */
827 cc = _edje_color_class_find(ed, tuple->key);
828 if (!cc) return EINA_FALSE;
829 et->cc = *cc;
830
831 /*
832 Any of the Edje object referenced should have a file with a valid
833 description for this color class. Let's bet on that for now.
834 */
835 if (ed->file)
836 cc = eina_hash_find(ed->file->color_hash, tuple->key);
837 if (!cc) return EINA_FALSE;
838 et->cc.desc = cc->desc;
839
840 *data = &et->cc;
841
842 return EINA_TRUE;
843 }
844
845 static void *
_edje_color_class_active_iterator_container(Eina_Iterator * it EINA_UNUSED)846 _edje_color_class_active_iterator_container(Eina_Iterator *it EINA_UNUSED)
847 {
848 return NULL;
849 }
850
851 static void
_edje_color_class_active_iterator_free(Eina_Iterator * it)852 _edje_color_class_active_iterator_free(Eina_Iterator *it)
853 {
854 Edje_Active_Color_Class_Iterator *et = (void *)it;
855
856 eina_iterator_free(et->classes);
857 EINA_MAGIC_SET(&et->iterator, 0);
858 free(et);
859 }
860
861 EAPI Eina_Iterator *
edje_color_class_active_iterator_new(void)862 edje_color_class_active_iterator_new(void)
863 {
864 Edje_Active_Color_Class_Iterator *it;
865
866 if (!_edje_color_class_member) return NULL;
867 it = calloc(1, sizeof (Edje_Active_Color_Class_Iterator));
868 if (!it) return NULL;
869
870 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
871 it->classes = efl_observable_iterator_tuple_new(_edje_color_class_member);
872
873 it->iterator.version = EINA_ITERATOR_VERSION;
874 it->iterator.next = _edje_color_class_active_iterator_next;
875 it->iterator.get_container = _edje_color_class_active_iterator_container;
876 it->iterator.free = _edje_color_class_active_iterator_free;
877
878 return &it->iterator;
879 }
880
881 static Eina_Bool
_edje_color_class_list_foreach(const Eina_Hash * hash EINA_UNUSED,const void * key,void * data EINA_UNUSED,void * fdata)882 _edje_color_class_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata)
883 {
884 Edje_List_Foreach_Data *fd;
885
886 fd = fdata;
887 fd->list = eina_list_append(fd->list, strdup(key));
888 return EINA_TRUE;
889 }
890
891 EAPI Eina_Bool
edje_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)892 edje_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)
893 {
894 Eina_Bool int_ret = EINA_TRUE;
895
896 int_ret &= efl_gfx_color_class_set(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a);
897 int_ret &= efl_gfx_color_class_set(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2);
898 int_ret &= efl_gfx_color_class_set(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3);
899
900 return int_ret;
901 }
902
903 EOLIAN Eina_Bool
_efl_canvas_layout_efl_gfx_color_class_color_class_set(Eo * obj EINA_UNUSED,Edje * ed,const char * color_class,Efl_Gfx_Color_Class_Layer layer,int r,int g,int b,int a)904 _efl_canvas_layout_efl_gfx_color_class_color_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *color_class, Efl_Gfx_Color_Class_Layer layer, int r, int g, int b, int a)
905 {
906 Eina_Bool int_ret;
907 Eina_Bool need_update;
908
909 int_ret = _edje_color_class_set_internal(ed->color_classes, color_class, layer, r, g, b, a, &need_update);
910
911 if ((int_ret) && (need_update))
912 {
913 Edje_Real_Part *rp;
914 unsigned short i;
915
916 ed->dirty = EINA_TRUE;
917 ed->recalc_call = EINA_TRUE;
918 #ifdef EDJE_CALC_CACHE
919 ed->all_part_change = EINA_TRUE;
920 #endif
921 for (i = 0; i < ed->table_parts_size; i++)
922 {
923 rp = ed->table_parts[i];
924 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
925 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
926 (rp->typedata.swallow)) &&
927 (rp->typedata.swallow->swallowed_object))
928 efl_gfx_color_class_set(rp->typedata.swallow->swallowed_object,
929 color_class, layer, r, g, b, a);
930 }
931
932 _edje_recalc(ed);
933 _edje_emit(ed, "color_class,set", color_class);
934 }
935
936 return int_ret;
937 }
938
939 EAPI Eina_Bool
edje_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)940 edje_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)
941 {
942 Eina_Bool int_ret = EINA_TRUE;
943
944 int_ret &= efl_gfx_color_class_get(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_NORMAL, r, g, b, a);
945 int_ret &= efl_gfx_color_class_get(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_OUTLINE, r2, g2, b2, a2);
946 int_ret &= efl_gfx_color_class_get(obj, color_class, EFL_GFX_COLOR_CLASS_LAYER_SHADOW, r3, g3, b3, a3);
947
948 return int_ret;
949 }
950
951 EOLIAN Eina_Bool
_efl_canvas_layout_efl_gfx_color_class_color_class_get(const Eo * obj EINA_UNUSED,Edje * ed,const char * color_class,Efl_Gfx_Color_Class_Layer layer,int * r,int * g,int * b,int * a)952 _efl_canvas_layout_efl_gfx_color_class_color_class_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *color_class, Efl_Gfx_Color_Class_Layer layer, int *r, int *g, int *b, int *a)
953 {
954 Edje_Color_Class *cc;
955
956 if (!color_class)
957 cc = NULL;
958 else
959 cc = _edje_color_class_find(ed, color_class);
960
961 return _edje_color_class_get_internal(cc, layer, r, g, b, a);
962 }
963
964 EAPI const char *
edje_object_color_class_description_get(const Evas_Object * obj,const char * color_class)965 edje_object_color_class_description_get(const Evas_Object *obj, const char *color_class)
966 {
967 return efl_gfx_color_class_description_get(obj, color_class);
968 }
969
970 EOLIAN const char *
_efl_canvas_layout_efl_gfx_color_class_color_class_description_get(const Eo * obj EINA_UNUSED,Edje * ed,const char * color_class)971 _efl_canvas_layout_efl_gfx_color_class_color_class_description_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *color_class)
972 {
973 Edje_Color_Class *cc = _edje_color_class_find(ed, color_class);
974 return cc ? cc->desc : NULL;
975 }
976
977 EAPI void
edje_object_color_class_del(Evas_Object * obj,const char * color_class)978 edje_object_color_class_del(Evas_Object *obj, const char *color_class)
979 {
980 efl_gfx_color_class_del(obj, color_class);
981 }
982
983 EOLIAN void
_efl_canvas_layout_efl_gfx_color_class_color_class_del(Eo * obj EINA_UNUSED,Edje * ed,const char * color_class)984 _efl_canvas_layout_efl_gfx_color_class_color_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *color_class)
985 {
986 Edje_Color_Class *cc = NULL;
987 unsigned short i;
988
989 if (!color_class) return;
990
991 eina_hash_del(ed->color_classes, color_class, cc);
992
993 for (i = 0; i < ed->table_parts_size; i++)
994 {
995 Edje_Real_Part *rp;
996
997 rp = ed->table_parts[i];
998 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
999 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
1000 (rp->typedata.swallow)) &&
1001 (rp->typedata.swallow->swallowed_object))
1002 efl_gfx_color_class_del(rp->typedata.swallow->swallowed_object, color_class);
1003 }
1004
1005 ed->dirty = EINA_TRUE;
1006 ed->recalc_call = EINA_TRUE;
1007 #ifdef EDJE_CALC_CACHE
1008 ed->all_part_change = EINA_TRUE;
1009 #endif
1010 _edje_recalc(ed);
1011 _edje_emit(ed, "color_class,del", color_class);
1012 }
1013
1014 EAPI Eina_Bool
edje_object_color_class_clear(const Evas_Object * obj)1015 edje_object_color_class_clear(const Evas_Object *obj)
1016 {
1017 efl_gfx_color_class_clear((Eo *)obj);
1018
1019 return EINA_TRUE;
1020 }
1021
1022 EOLIAN void
_efl_canvas_layout_efl_gfx_color_class_color_class_clear(Eo * obj EINA_UNUSED,Edje * ed)1023 _efl_canvas_layout_efl_gfx_color_class_color_class_clear(Eo *obj EINA_UNUSED, Edje *ed)
1024 {
1025 Edje_List_Foreach_Data fdata;
1026 Edje_Color_Class *cc = NULL;
1027 Eina_List *l;
1028 char *color_class;
1029 unsigned short i;
1030
1031 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
1032 eina_hash_foreach(ed->color_classes, _edje_color_class_list_foreach, &fdata);
1033
1034 EINA_LIST_FOREACH(fdata.list, l, color_class)
1035 eina_hash_del(ed->color_classes, color_class, cc);
1036
1037 for (i = 0; i < ed->table_parts_size; i++)
1038 {
1039 Edje_Real_Part *rp;
1040
1041 rp = ed->table_parts[i];
1042 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
1043 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
1044 (rp->typedata.swallow)) &&
1045 (rp->typedata.swallow->swallowed_object))
1046 efl_gfx_color_class_clear(rp->typedata.swallow->swallowed_object);
1047 }
1048
1049 ed->dirty = EINA_TRUE;
1050 ed->recalc_call = EINA_TRUE;
1051 #ifdef EDJE_CALC_CACHE
1052 ed->all_part_change = EINA_TRUE;
1053 #endif
1054 _edje_recalc(ed);
1055
1056 EINA_LIST_FREE(fdata.list, color_class)
1057 {
1058 _edje_emit(ed, "color_class,del", color_class);
1059 free(color_class);
1060 }
1061 }
1062
1063 typedef struct _Edje_File_Color_Class_Iterator Edje_File_Color_Class_Iterator;
1064 struct _Edje_File_Color_Class_Iterator
1065 {
1066 Edje_Active_Color_Class_Iterator it;
1067
1068 Edje_File *edf;
1069 };
1070
1071 static Eina_Bool
_edje_mmap_color_class_iterator_next(Eina_Iterator * it,void ** data)1072 _edje_mmap_color_class_iterator_next(Eina_Iterator *it, void **data)
1073 {
1074 Edje_File_Color_Class_Iterator *et = (void *)it;
1075 Eina_Hash_Tuple *tuple = NULL;
1076 Edje_Color_Class *cc = NULL;
1077
1078 if (!eina_iterator_next(et->it.classes, (void **)&tuple)) return EINA_FALSE;
1079 if (!tuple) return EINA_FALSE;
1080
1081 cc = tuple->data;
1082
1083 et->it.cc = *cc;
1084
1085 *data = &et->it.cc;
1086 return EINA_TRUE;
1087 }
1088
1089 static void *
_edje_mmap_color_class_iterator_container(Eina_Iterator * it)1090 _edje_mmap_color_class_iterator_container(Eina_Iterator *it)
1091 {
1092 Edje_File_Color_Class_Iterator *et = (void *)it;
1093
1094 return et->edf->f;
1095 }
1096
1097 static void
_edje_mmap_color_class_iterator_free(Eina_Iterator * it)1098 _edje_mmap_color_class_iterator_free(Eina_Iterator *it)
1099 {
1100 Edje_File_Color_Class_Iterator *et = (void *)it;
1101
1102 eina_iterator_free(et->it.classes);
1103 _edje_cache_file_unref(et->edf);
1104 EINA_MAGIC_SET(&et->it.iterator, 0);
1105 free(et);
1106 }
1107
1108 EAPI Eina_Iterator *
edje_mmap_color_class_iterator_new(Eina_File * f)1109 edje_mmap_color_class_iterator_new(Eina_File *f)
1110 {
1111 Edje_File_Color_Class_Iterator *it;
1112 Edje_File *edf;
1113 int error_ret;
1114
1115 edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
1116 if (!edf) return NULL;
1117
1118 it = calloc(1, sizeof (Edje_File_Color_Class_Iterator));
1119 if (!it) goto on_error;
1120
1121 EINA_MAGIC_SET(&it->it.iterator, EINA_MAGIC_ITERATOR);
1122 it->edf = edf;
1123 it->it.classes = eina_hash_iterator_tuple_new(edf->color_hash);
1124
1125 it->it.iterator.version = EINA_ITERATOR_VERSION;
1126 it->it.iterator.next = _edje_mmap_color_class_iterator_next;
1127 it->it.iterator.get_container = _edje_mmap_color_class_iterator_container;
1128 it->it.iterator.free = _edje_mmap_color_class_iterator_free;
1129
1130 return &it->it.iterator;
1131
1132 on_error:
1133 _edje_cache_file_unref(edf);
1134 return NULL;
1135 }
1136
1137 EAPI Eina_Bool
edje_text_class_set(const char * text_class,const char * font,Evas_Font_Size size)1138 edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size)
1139 {
1140 return efl_gfx_text_class_set(_edje_global(), text_class, font, (Efl_Font_Size)size);
1141 }
1142
1143 EOLIAN Eina_Bool
_edje_global_efl_gfx_text_class_text_class_set(Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * text_class,const char * font,Efl_Font_Size size)1144 _edje_global_efl_gfx_text_class_text_class_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
1145 const char *text_class, const char *font, Efl_Font_Size size)
1146 {
1147 Edje_Text_Class *tc;
1148
1149 if (!text_class) return EINA_FALSE;
1150 if (!font) font = "";
1151
1152 tc = eina_hash_find(_edje_text_class_hash, text_class);
1153 /* Create new text class */
1154 if (!tc)
1155 {
1156 tc = calloc(1, sizeof(Edje_Text_Class));
1157 if (!tc) return EINA_FALSE;
1158 tc->name = eina_stringshare_add(text_class);
1159 if (!tc->name)
1160 {
1161 free(tc);
1162 return EINA_FALSE;
1163 }
1164 if (!_edje_text_class_hash) _edje_text_class_hash = eina_hash_string_superfast_new(NULL);
1165 eina_hash_add(_edje_text_class_hash, text_class, tc);
1166
1167 tc->font = eina_stringshare_add(font);
1168 tc->size = size;
1169 }
1170 else
1171 {
1172 /* Match and the same, return */
1173 if (((tc->font && font) && !strcmp(tc->font, font)) &&
1174 (tc->size == size))
1175 return EINA_TRUE;
1176
1177 /* Update the class found */
1178 eina_stringshare_replace(&tc->font, font);
1179 tc->size = size;
1180 }
1181
1182 /* Tell all members of the text class to recalc */
1183 efl_observable_observers_update(_edje_text_class_member, text_class, NULL);
1184
1185 return EINA_TRUE;
1186 }
1187
1188 EAPI Eina_Bool
edje_text_class_get(const char * text_class,const char ** font,Evas_Font_Size * size)1189 edje_text_class_get(const char *text_class, const char **font, Evas_Font_Size *size)
1190 {
1191 return efl_gfx_text_class_get(_edje_global(), text_class, font, (Efl_Font_Size *)size);
1192 }
1193
1194 EOLIAN Eina_Bool
_edje_global_efl_gfx_text_class_text_class_get(const Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * text_class,const char ** font,Efl_Font_Size * size)1195 _edje_global_efl_gfx_text_class_text_class_get(const Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
1196 const char *text_class, const char **font, Efl_Font_Size *size)
1197 {
1198 Edje_Text_Class *tc;
1199
1200 if (!text_class) return EINA_FALSE;
1201
1202 tc = eina_hash_find(_edje_text_class_hash, text_class);
1203
1204 if (tc)
1205 {
1206 if (font) *font = tc->font;
1207 if (size) *size = tc->size;
1208 }
1209 else
1210 {
1211 if (font) *font = NULL;
1212 if (size) *size = 0;
1213
1214 return EINA_FALSE;
1215 }
1216 return EINA_TRUE;
1217 }
1218
1219 EAPI void
edje_text_class_del(const char * text_class)1220 edje_text_class_del(const char *text_class)
1221 {
1222 efl_gfx_text_class_del(_edje_global(), text_class);
1223 }
1224
1225 EOLIAN void
_edje_global_efl_gfx_text_class_text_class_del(Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * text_class)1226 _edje_global_efl_gfx_text_class_text_class_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *text_class)
1227 {
1228 Edje_Text_Class *tc;
1229
1230 if (!text_class) return;
1231
1232 tc = eina_hash_find(_edje_text_class_hash, text_class);
1233 if (!tc) return;
1234
1235 eina_hash_del(_edje_text_class_hash, text_class, tc);
1236 eina_stringshare_del(tc->name);
1237 eina_stringshare_del(tc->font);
1238 free(tc);
1239
1240 efl_observable_observers_update(_edje_text_class_member, text_class, NULL);
1241 }
1242
1243 Eina_List *
edje_text_class_list(void)1244 edje_text_class_list(void)
1245 {
1246 Edje_List_Foreach_Data fdata;
1247
1248 if (!_edje_text_class_hash) return NULL;
1249 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
1250 eina_hash_foreach(_edje_text_class_hash,
1251 _edje_text_class_list_foreach, &fdata);
1252 return fdata.list;
1253 }
1254
1255 typedef struct _Edje_Active_Text_Class_Iterator Edje_Active_Text_Class_Iterator;
1256 struct _Edje_Active_Text_Class_Iterator
1257 {
1258 Eina_Iterator iterator;
1259 Edje_Text_Class tc;
1260 Eina_Iterator *classes;
1261 };
1262
1263 static Eina_Bool
_edje_text_class_active_iterator_next(Eina_Iterator * it,void ** data)1264 _edje_text_class_active_iterator_next(Eina_Iterator *it, void **data)
1265 {
1266 Edje_Active_Text_Class_Iterator *et = (void *)it;
1267 Efl_Observable_Tuple *tuple = NULL;
1268 Efl_Observer *o;
1269 Edje *ed;
1270 Edje_Text_Class *tc;
1271
1272 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
1273 if (!tuple) return EINA_FALSE;
1274
1275 if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
1276
1277 ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
1278 if (!ed) return EINA_FALSE;
1279
1280 /*
1281 We actually need to ask on an object to get the correct value.
1282 It is being assumed that the size key are the same for all object here.
1283 This can some times not be the case, but for now we should be fine.
1284 */
1285 tc = _edje_text_class_find(ed, tuple->key);
1286 if (!tc) return EINA_FALSE;
1287 et->tc = *tc;
1288
1289 *data = &et->tc;
1290
1291 return EINA_TRUE;
1292 }
1293
1294 static void *
_edje_text_class_active_iterator_container(Eina_Iterator * it EINA_UNUSED)1295 _edje_text_class_active_iterator_container(Eina_Iterator *it EINA_UNUSED)
1296 {
1297 return NULL;
1298 }
1299
1300 static void
_edje_text_class_active_iterator_free(Eina_Iterator * it)1301 _edje_text_class_active_iterator_free(Eina_Iterator *it)
1302 {
1303 Edje_Active_Text_Class_Iterator *et = (void *)it;
1304
1305 eina_iterator_free(et->classes);
1306 EINA_MAGIC_SET(&et->iterator, 0);
1307 free(et);
1308 }
1309
1310 EAPI Eina_Iterator *
edje_text_class_active_iterator_new(void)1311 edje_text_class_active_iterator_new(void)
1312 {
1313 Edje_Active_Text_Class_Iterator *it;
1314
1315 if (!_edje_text_class_member) return NULL;
1316 it = calloc(1, sizeof (Edje_Active_Text_Class_Iterator));
1317 if (!it) return NULL;
1318
1319 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1320 it->classes = efl_observable_iterator_tuple_new(_edje_text_class_member);
1321
1322 it->iterator.version = EINA_ITERATOR_VERSION;
1323 it->iterator.next = _edje_text_class_active_iterator_next;
1324 it->iterator.get_container = _edje_text_class_active_iterator_container;
1325 it->iterator.free = _edje_text_class_active_iterator_free;
1326
1327 return &it->iterator;
1328 }
1329
1330 static Eina_Bool
_edje_text_class_list_foreach(const Eina_Hash * hash EINA_UNUSED,const void * key,void * data EINA_UNUSED,void * fdata)1331 _edje_text_class_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata)
1332 {
1333 Edje_List_Foreach_Data *fd;
1334
1335 fd = fdata;
1336 fd->list = eina_list_append(fd->list, eina_stringshare_add(key));
1337 return EINA_TRUE;
1338 }
1339
1340 static Edje_File *
_edje_file_find(const char * file)1341 _edje_file_find(const char *file)
1342 {
1343 char *tmp = NULL;
1344 Eina_File *f = NULL;
1345 Edje_File *edf = NULL;
1346
1347 if (!file) return NULL;
1348
1349 tmp = eina_vpath_resolve(file);
1350 if (!tmp) return NULL;
1351
1352 f = eina_file_open(tmp, EINA_FALSE);
1353
1354 if (tmp) free(tmp);
1355 if (!f) return NULL;
1356
1357 edf = _edje_file_cache_find(f);
1358
1359 eina_file_close(f);
1360 return edf;
1361 }
1362
1363 EAPI Eina_Bool
edje_file_text_class_get(const char * file,const char * text_class,const char ** font,Evas_Font_Size * size)1364 edje_file_text_class_get(const char *file, const char * text_class, const char **font, Evas_Font_Size *size)
1365 {
1366 Edje_Text_Class *tc = NULL;
1367 Edje_File *edf = NULL;
1368 Eina_Bool ret = EINA_FALSE;
1369
1370 if (font) *font = NULL;
1371 if (size) *size = 0;
1372
1373 if ((!file) || (!text_class)) return ret;
1374 if ((!font) && (!size)) return ret; // No need to go deep
1375
1376 edf = _edje_file_find(file);
1377 if (!edf) return ret;
1378
1379 tc = eina_hash_find(edf->text_hash, text_class);
1380 if (!tc) goto end;
1381
1382 if (font) *font = tc->font;
1383 if (size) *size = tc->size;
1384 ret = EINA_TRUE;
1385
1386 end:
1387 _edje_cache_file_unref(edf);
1388 return ret;
1389 }
1390
1391 EAPI Eina_Bool
edje_file_text_class_del(const char * file,const char * text_class)1392 edje_file_text_class_del(const char *file, const char *text_class)
1393 {
1394 Edje_Text_Class *tc = NULL;
1395 Edje_File *edf = NULL;
1396 Eina_Bool ret = EINA_FALSE;
1397 if ((!file) || (!text_class)) return ret;
1398
1399 edf = _edje_file_find(file);
1400 if (!edf) return ret;
1401
1402 tc = eina_hash_find(edf->text_hash, text_class);
1403 if (!tc) goto end;
1404
1405 eina_hash_del(edf->text_hash, text_class, tc);
1406 eina_stringshare_del(tc->name);
1407 eina_stringshare_del(tc->font);
1408 free(tc);
1409
1410 /* Tell all members of the text class to recalc */
1411 efl_observable_observers_update(_edje_text_class_member, text_class, edf);
1412
1413 ret = EINA_TRUE;
1414 end:
1415 _edje_cache_file_unref(edf);
1416 return ret;
1417 }
1418
1419 EAPI Eina_Bool
edje_file_text_class_set(const char * file,const char * text_class,const char * font,Evas_Font_Size size)1420 edje_file_text_class_set(const char *file, const char *text_class, const char *font, Evas_Font_Size size)
1421 {
1422 Edje_File *edf = NULL;
1423 Edje_Text_Class *tc = NULL;
1424 Eina_Bool ret = EINA_FALSE;
1425
1426 if ((!file) || (!text_class)) return ret;
1427
1428 edf = _edje_file_find(file);
1429 if (!edf) return ret;
1430
1431 // update text_class properties, or create new text_class if not found
1432 if (edf->text_hash) tc = eina_hash_find(edf->text_hash, text_class);
1433 if (!tc)
1434 {
1435 /* Create new text class */
1436 tc = calloc(1, sizeof(Edje_Text_Class));
1437 if (!tc) goto error_end;
1438 tc->name = eina_stringshare_add(text_class);
1439 if (!tc->name)
1440 {
1441 free(tc);
1442 goto error_end;
1443 }
1444 if (!edf->text_hash) edf->text_hash = eina_hash_string_small_new(NULL);
1445 eina_hash_direct_add(edf->text_hash, text_class, tc);
1446
1447 tc->font = eina_stringshare_add(font);
1448 tc->size = size;
1449 }
1450 else
1451 {
1452 /* Match and the same, return */
1453 if (((tc->font && font) && !strcmp(tc->font, font)) &&
1454 (tc->size == size))
1455 goto success_end;
1456
1457 /* Update the class found */
1458 eina_stringshare_replace(&tc->font, font);
1459 tc->size = size;
1460 }
1461
1462
1463 /* Tell all members of the text class to recalc */
1464 efl_observable_observers_update(_edje_text_class_member, text_class, edf);
1465
1466 success_end:
1467 ret = EINA_TRUE;
1468
1469 error_end:
1470 _edje_cache_file_unref(edf);
1471 return ret;
1472 }
1473
1474 EAPI Eina_Bool
edje_object_text_class_set(Evas_Object * obj,const char * text_class,const char * font,Evas_Font_Size size)1475 edje_object_text_class_set(Evas_Object *obj, const char *text_class, const char *font, Evas_Font_Size size)
1476 {
1477 return efl_gfx_text_class_set(obj, text_class, font, (Efl_Font_Size)size);
1478 }
1479
1480 EOLIAN Eina_Bool
_efl_canvas_layout_efl_gfx_text_class_text_class_set(Eo * obj EINA_UNUSED,Edje * ed,const char * text_class,const char * font,Efl_Font_Size size)1481 _efl_canvas_layout_efl_gfx_text_class_text_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *text_class, const char *font, Efl_Font_Size size)
1482 {
1483 Edje_Text_Class *tc = NULL;
1484 unsigned short i;
1485
1486 if ((!ed) || (!text_class)) return EINA_FALSE;
1487
1488 tc = eina_hash_find(ed->text_classes, text_class);
1489
1490 /* for each text_class in the edje */
1491 if (tc)
1492 {
1493 if ((tc->name) && (!strcmp(tc->name, text_class)))
1494 {
1495 /* Match and the same, return */
1496 if ((tc->size == size) &&
1497 ((tc->font == font) ||
1498 (tc->font && font && !strcmp(tc->font, font))))
1499 {
1500 return EINA_TRUE;
1501 }
1502
1503 /* Update new text class properties */
1504 eina_stringshare_replace(&tc->font, font);
1505 tc->size = size;
1506 }
1507 }
1508
1509 if (!tc)
1510 {
1511 /* No matches, create a new text class */
1512 tc = calloc(1, sizeof(Edje_Text_Class));
1513 if (!tc) return EINA_FALSE;
1514 tc->name = eina_stringshare_add(text_class);
1515 if (!tc->name)
1516 {
1517 free(tc);
1518 return EINA_FALSE;
1519 }
1520 tc->font = eina_stringshare_add(font);
1521 tc->size = size;
1522 /* Add to edje's text class list */
1523 eina_hash_direct_add(ed->text_classes, tc->name, tc);
1524 }
1525
1526 for (i = 0; i < ed->table_parts_size; i++)
1527 {
1528 Edje_Real_Part *rp;
1529
1530 rp = ed->table_parts[i];
1531 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
1532 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
1533 (rp->typedata.swallow)) &&
1534 (rp->typedata.swallow->swallowed_object))
1535 efl_gfx_text_class_set(rp->typedata.swallow->swallowed_object,
1536 text_class, font, size);
1537 }
1538
1539 efl_observer_update(obj, _edje_text_class_member, text_class, ed);
1540
1541 return EINA_TRUE;
1542 }
1543
1544 EAPI Eina_Bool
edje_object_text_class_get(const Evas_Object * obj,const char * text_class,const char ** font,Evas_Font_Size * size)1545 edje_object_text_class_get(const Evas_Object *obj, const char *text_class, const char **font, Evas_Font_Size *size)
1546 {
1547 return efl_gfx_text_class_get(obj, text_class, font, (Efl_Font_Size *)size);
1548 }
1549
1550 EOLIAN Eina_Bool
_efl_canvas_layout_efl_gfx_text_class_text_class_get(const Eo * obj EINA_UNUSED,Edje * ed,const char * text_class,const char ** font,Efl_Font_Size * size)1551 _efl_canvas_layout_efl_gfx_text_class_text_class_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *text_class, const char **font, Efl_Font_Size *size)
1552 {
1553 Edje_Text_Class *tc = _edje_text_class_find(ed, text_class);
1554
1555 if (tc)
1556 {
1557 if (font) *font = tc->font;
1558 if (size) *size = tc->size;
1559 }
1560 else
1561 {
1562 if (font) *font = NULL;
1563 if (size) *size = 0;
1564
1565 return EINA_FALSE;
1566 }
1567 return EINA_TRUE;
1568 }
1569
1570 EAPI void
edje_object_text_class_del(Evas_Object * obj,const char * text_class)1571 edje_object_text_class_del(Evas_Object *obj, const char *text_class)
1572 {
1573 efl_gfx_text_class_del(obj, text_class);
1574 }
1575
1576 EOLIAN void
_efl_canvas_layout_efl_gfx_text_class_text_class_del(Eo * obj EINA_UNUSED,Edje * ed,const char * text_class)1577 _efl_canvas_layout_efl_gfx_text_class_text_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *text_class)
1578 {
1579 Edje_Text_Class *tc = NULL;
1580 unsigned short i;
1581
1582 if (!text_class) return;
1583
1584 eina_hash_del(ed->text_classes, text_class, tc);
1585
1586 for (i = 0; i < ed->table_parts_size; i++)
1587 {
1588 Edje_Real_Part *rp;
1589
1590 rp = ed->table_parts[i];
1591 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
1592 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
1593 (rp->typedata.swallow)) &&
1594 (rp->typedata.swallow->swallowed_object))
1595 efl_gfx_text_class_del(rp->typedata.swallow->swallowed_object, text_class);
1596 }
1597
1598 efl_observer_update(obj, _edje_text_class_member, text_class, ed);
1599 }
1600
1601 typedef struct _Edje_File_Text_Class_Iterator Edje_File_Text_Class_Iterator;
1602 struct _Edje_File_Text_Class_Iterator
1603 {
1604 Edje_Active_Text_Class_Iterator it;
1605
1606 Edje_File *edf;
1607 };
1608
1609 static Eina_Bool
_edje_mmap_text_class_iterator_next(Eina_Iterator * it,void ** data)1610 _edje_mmap_text_class_iterator_next(Eina_Iterator *it, void **data)
1611 {
1612 Edje_File_Text_Class_Iterator *et = (void *)it;
1613 Eina_Hash_Tuple *tuple = NULL;
1614 Edje_Text_Class *tc = NULL;
1615
1616 if (!eina_iterator_next(et->it.classes, (void **)&tuple)) return EINA_FALSE;
1617 if (!tuple) return EINA_FALSE;
1618
1619 tc = tuple->data;
1620
1621 et->it.tc = *tc;
1622
1623 *data = &et->it.tc;
1624 return EINA_TRUE;
1625 }
1626
1627 static void *
_edje_mmap_text_class_iterator_container(Eina_Iterator * it)1628 _edje_mmap_text_class_iterator_container(Eina_Iterator *it)
1629 {
1630 Edje_File_Text_Class_Iterator *et = (void *)it;
1631
1632 return et->edf->f;
1633 }
1634
1635 static void
_edje_mmap_text_class_iterator_free(Eina_Iterator * it)1636 _edje_mmap_text_class_iterator_free(Eina_Iterator *it)
1637 {
1638 Edje_File_Text_Class_Iterator *et = (void *)it;
1639
1640 eina_iterator_free(et->it.classes);
1641 _edje_cache_file_unref(et->edf);
1642 EINA_MAGIC_SET(&et->it.iterator, 0);
1643 free(et);
1644 }
1645
1646 EAPI Eina_Iterator *
edje_mmap_text_class_iterator_new(Eina_File * f)1647 edje_mmap_text_class_iterator_new(Eina_File *f)
1648 {
1649 Edje_File_Text_Class_Iterator *it;
1650 Edje_File *edf;
1651 int error_ret;
1652
1653 edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
1654 if (!edf) return NULL;
1655
1656 it = calloc(1, sizeof (Edje_File_Text_Class_Iterator));
1657 if (!it) goto on_error;
1658
1659 EINA_MAGIC_SET(&it->it.iterator, EINA_MAGIC_ITERATOR);
1660 it->edf = edf;
1661 it->it.classes = eina_hash_iterator_tuple_new(edf->text_hash);
1662
1663 it->it.iterator.version = EINA_ITERATOR_VERSION;
1664 it->it.iterator.next = _edje_mmap_text_class_iterator_next;
1665 it->it.iterator.get_container = _edje_mmap_text_class_iterator_container;
1666 it->it.iterator.free = _edje_mmap_text_class_iterator_free;
1667
1668 return &it->it.iterator;
1669
1670 on_error:
1671 _edje_cache_file_unref(edf);
1672 return NULL;
1673 }
1674
1675 EAPI Eina_Bool
edje_size_class_set(const char * size_class,Evas_Coord minw,Evas_Coord minh,Evas_Coord maxw,Evas_Coord maxh)1676 edje_size_class_set(const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
1677 {
1678 return efl_gfx_size_class_set(_edje_global(), size_class, minw, minh, maxw, maxh);
1679 }
1680
1681 EOLIAN Eina_Bool
_edje_global_efl_gfx_size_class_size_class_set(Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * size_class,Evas_Coord minw,Evas_Coord minh,Evas_Coord maxw,Evas_Coord maxh)1682 _edje_global_efl_gfx_size_class_size_class_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *size_class,
1683 Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
1684 {
1685 Edje_Size_Class *sc;
1686
1687 if (!size_class) return EINA_FALSE;
1688
1689 sc = eina_hash_find(_edje_size_class_hash, size_class);
1690 /* Create new size class */
1691 if (!sc)
1692 {
1693 sc = calloc(1, sizeof(Edje_Size_Class));
1694 if (!sc) return EINA_FALSE;
1695 sc->name = eina_stringshare_add(size_class);
1696 if (!sc->name)
1697 {
1698 free(sc);
1699 return EINA_FALSE;
1700 }
1701 if (!_edje_size_class_hash) _edje_size_class_hash = eina_hash_string_superfast_new(NULL);
1702 eina_hash_add(_edje_size_class_hash, size_class, sc);
1703
1704 sc->minw = minw;
1705 sc->minh = minh;
1706 sc->maxw = maxw;
1707 sc->maxh = maxh;
1708 }
1709 else
1710 {
1711 /* Match and the same, return */
1712 if ((sc->minw == minw) && (sc->minh == minh) &&
1713 (sc->maxw == maxw) && (sc->maxh == maxh))
1714 return EINA_TRUE;
1715
1716 /* Update the class found */
1717 sc->minw = minw;
1718 sc->minh = minh;
1719 sc->maxw = maxw;
1720 sc->maxh = maxh;
1721 }
1722
1723 /* Tell all members of the size class to recalc */
1724 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
1725
1726 return EINA_TRUE;
1727 }
1728
1729 EAPI Eina_Bool
edje_size_class_get(const char * size_class,Evas_Coord * minw,Evas_Coord * minh,Evas_Coord * maxw,Evas_Coord * maxh)1730 edje_size_class_get(const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
1731 {
1732 return efl_gfx_size_class_get(_edje_global(), size_class, minw, minh, maxw, maxh);
1733 }
1734
1735 EOLIAN Eina_Bool
_edje_global_efl_gfx_size_class_size_class_get(const Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * size_class,Evas_Coord * minw,Evas_Coord * minh,Evas_Coord * maxw,Evas_Coord * maxh)1736 _edje_global_efl_gfx_size_class_size_class_get(const Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *size_class,
1737 Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
1738 {
1739 Edje_Size_Class *sc;
1740
1741 if (!size_class) return EINA_FALSE;
1742
1743 sc = eina_hash_find(_edje_size_class_hash, size_class);
1744
1745 if (sc)
1746 {
1747 if (minw) *minw = sc->minw;
1748 if (minh) *minh = sc->minh;
1749 if (maxw) *maxw = sc->maxw;
1750 if (maxh) *maxh = sc->maxh;
1751 }
1752 else
1753 {
1754 if (minw) *minw = 0;
1755 if (minh) *minh = 0;
1756 if (maxw) *maxw = 0;
1757 if (maxh) *maxh = 0;
1758
1759 return EINA_FALSE;
1760 }
1761 return EINA_TRUE;
1762 }
1763
1764 EAPI void
edje_size_class_del(const char * size_class)1765 edje_size_class_del(const char *size_class)
1766 {
1767 efl_gfx_size_class_del(_edje_global(), size_class);
1768 }
1769
1770 EOLIAN void
_edje_global_efl_gfx_size_class_size_class_del(Eo * obj EINA_UNUSED,void * pd EINA_UNUSED,const char * size_class)1771 _edje_global_efl_gfx_size_class_size_class_del(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, const char *size_class)
1772 {
1773 Edje_Size_Class *sc;
1774
1775 if (!size_class) return;
1776
1777 sc = eina_hash_find(_edje_size_class_hash, size_class);
1778 if (!sc) return;
1779
1780 eina_hash_del(_edje_size_class_hash, size_class, sc);
1781 eina_stringshare_del(sc->name);
1782 free(sc);
1783
1784 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
1785 }
1786
1787 Eina_List *
edje_size_class_list(void)1788 edje_size_class_list(void)
1789 {
1790 Edje_List_Foreach_Data fdata;
1791
1792 if (!_edje_size_class_hash) return NULL;
1793 memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
1794 eina_hash_foreach(_edje_size_class_hash,
1795 _edje_size_class_list_foreach, &fdata);
1796 return fdata.list;
1797 }
1798
1799 typedef struct _Edje_Active_Size_Class_Iterator Edje_Active_Size_Class_Iterator;
1800 struct _Edje_Active_Size_Class_Iterator
1801 {
1802 Eina_Iterator iterator;
1803 Edje_Size_Class sc;
1804 Eina_Iterator *classes;
1805 };
1806
1807 static Eina_Bool
_edje_size_class_active_iterator_next(Eina_Iterator * it,void ** data)1808 _edje_size_class_active_iterator_next(Eina_Iterator *it, void **data)
1809 {
1810 Edje_Active_Size_Class_Iterator *et = (void *)it;
1811 Efl_Observable_Tuple *tuple = NULL;
1812 Efl_Observer *o;
1813 Edje *ed;
1814 Edje_Size_Class *sc;
1815
1816 if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE;
1817 if (!tuple) return EINA_FALSE;
1818
1819 if (!eina_iterator_next(tuple->data, (void **)&o)) return EINA_FALSE;
1820
1821 ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
1822 if (!ed) return EINA_FALSE;
1823
1824 /*
1825 We actually need to ask on an object to get the correct value.
1826 It is being assumed that the size key are the same for all object here.
1827 This can some times not be the case, but for now we should be fine.
1828 */
1829 sc = _edje_size_class_find(ed, tuple->key);
1830 if (!sc) return EINA_FALSE;
1831 et->sc = *sc;
1832
1833 *data = &et->sc;
1834
1835 return EINA_TRUE;
1836 }
1837
1838 static void *
_edje_size_class_active_iterator_container(Eina_Iterator * it EINA_UNUSED)1839 _edje_size_class_active_iterator_container(Eina_Iterator *it EINA_UNUSED)
1840 {
1841 return NULL;
1842 }
1843
1844 static void
_edje_size_class_active_iterator_free(Eina_Iterator * it)1845 _edje_size_class_active_iterator_free(Eina_Iterator *it)
1846 {
1847 Edje_Active_Size_Class_Iterator *et = (void *)it;
1848
1849 eina_iterator_free(et->classes);
1850 EINA_MAGIC_SET(&et->iterator, 0);
1851 free(et);
1852 }
1853
1854 EAPI Eina_Iterator *
edje_size_class_active_iterator_new(void)1855 edje_size_class_active_iterator_new(void)
1856 {
1857 Edje_Active_Size_Class_Iterator *it;
1858
1859 if (!_edje_size_class_member) return NULL;
1860 it = calloc(1, sizeof (Edje_Active_Size_Class_Iterator));
1861 if (!it) return NULL;
1862
1863 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1864 it->classes = efl_observable_iterator_tuple_new(_edje_size_class_member);
1865
1866 it->iterator.version = EINA_ITERATOR_VERSION;
1867 it->iterator.next = _edje_size_class_active_iterator_next;
1868 it->iterator.get_container = _edje_size_class_active_iterator_container;
1869 it->iterator.free = _edje_size_class_active_iterator_free;
1870
1871 return &it->iterator;
1872 }
1873
1874 static Eina_Bool
_edje_size_class_list_foreach(const Eina_Hash * hash EINA_UNUSED,const void * key,void * data EINA_UNUSED,void * fdata)1875 _edje_size_class_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata)
1876 {
1877 Edje_List_Foreach_Data *fd;
1878
1879 fd = fdata;
1880 fd->list = eina_list_append(fd->list, eina_stringshare_add(key));
1881 return EINA_TRUE;
1882 }
1883
1884 EAPI Eina_Bool
edje_object_size_class_set(Evas_Object * obj,const char * size_class,Evas_Coord minw,Evas_Coord minh,Evas_Coord maxw,Evas_Coord maxh)1885 edje_object_size_class_set(Evas_Object *obj, const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
1886 {
1887 return efl_gfx_size_class_set(obj, size_class, minw, minh, maxw, maxh);
1888 }
1889
1890 EOLIAN Eina_Bool
_efl_canvas_layout_efl_gfx_size_class_size_class_set(Eo * obj EINA_UNUSED,Edje * ed,const char * size_class,Evas_Coord minw,Evas_Coord minh,Evas_Coord maxw,Evas_Coord maxh)1891 _efl_canvas_layout_efl_gfx_size_class_size_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh)
1892 {
1893 Edje_Size_Class *sc = NULL;
1894 unsigned short i;
1895
1896 if ((!ed) || (!size_class)) return EINA_FALSE;
1897
1898 /* for each size_class in the edje */
1899 sc = eina_hash_find(ed->size_classes, size_class);
1900
1901 if (sc)
1902 {
1903 if ((sc->minw == minw) && (sc->minh == minh) &&
1904 (sc->maxw == maxw) && (sc->maxh == maxh))
1905 {
1906 return EINA_TRUE;
1907 }
1908
1909 /* Update new size class properties */
1910 sc->minw = minw;
1911 sc->minh = minh;
1912 sc->maxw = maxw;
1913 sc->maxh = maxh;
1914 }
1915 else
1916 {
1917 /* No matches, create a new size class */
1918 sc = calloc(1, sizeof(Edje_Size_Class));
1919 if (!sc) return EINA_FALSE;
1920 sc->name = eina_stringshare_add(size_class);
1921 if (!sc->name)
1922 {
1923 free(sc);
1924 return EINA_FALSE;
1925 }
1926 sc->minw = minw;
1927 sc->minh = minh;
1928 sc->maxw = maxw;
1929 sc->maxh = maxh;
1930 /* Add to edje's size class list */
1931 eina_hash_direct_add(ed->size_classes, sc->name, sc);
1932 }
1933
1934 for (i = 0; i < ed->table_parts_size; i++)
1935 {
1936 Edje_Real_Part *rp;
1937
1938 rp = ed->table_parts[i];
1939 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
1940 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
1941 (rp->typedata.swallow)) &&
1942 (rp->typedata.swallow->swallowed_object))
1943 efl_gfx_size_class_set(rp->typedata.swallow->swallowed_object,
1944 size_class, minw, minh, maxw, maxh);
1945 }
1946
1947 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
1948
1949 return EINA_TRUE;
1950 }
1951
1952 EAPI Eina_Bool
edje_object_size_class_get(const Evas_Object * obj,const char * size_class,Evas_Coord * minw,Evas_Coord * minh,Evas_Coord * maxw,Evas_Coord * maxh)1953 edje_object_size_class_get(const Evas_Object *obj, const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
1954 {
1955 return efl_gfx_size_class_get(obj, size_class, minw, minh, maxw, maxh);
1956 }
1957
1958 EOLIAN Eina_Bool
_efl_canvas_layout_efl_gfx_size_class_size_class_get(const Eo * obj EINA_UNUSED,Edje * ed,const char * size_class,Evas_Coord * minw,Evas_Coord * minh,Evas_Coord * maxw,Evas_Coord * maxh)1959 _efl_canvas_layout_efl_gfx_size_class_size_class_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh)
1960 {
1961 Edje_Size_Class *sc = _edje_size_class_find(ed, size_class);
1962
1963 if (sc)
1964 {
1965 if (minw) *minw = sc->minw;
1966 if (minh) *minh = sc->minh;
1967 if (maxw) *maxw = sc->maxw;
1968 if (maxh) *maxh = sc->maxh;
1969 }
1970 else
1971 {
1972 if (minw) *minw = 0;
1973 if (minh) *minh = 0;
1974 if (maxw) *maxw = 0;
1975 if (maxh) *maxh = 0;
1976
1977 return EINA_FALSE;
1978 }
1979 return EINA_TRUE;
1980 }
1981
1982 EAPI void
edje_object_size_class_del(Evas_Object * obj,const char * size_class)1983 edje_object_size_class_del(Evas_Object *obj, const char *size_class)
1984 {
1985 efl_gfx_size_class_del(obj, size_class);
1986 }
1987
1988 EOLIAN void
_efl_canvas_layout_efl_gfx_size_class_size_class_del(Eo * obj EINA_UNUSED,Edje * ed,const char * size_class)1989 _efl_canvas_layout_efl_gfx_size_class_size_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *size_class)
1990 {
1991 Edje_Size_Class *sc = NULL;
1992 unsigned short i;
1993
1994 if (!size_class) return;
1995
1996 eina_hash_del(ed->size_classes, size_class, sc);
1997
1998 for (i = 0; i < ed->table_parts_size; i++)
1999 {
2000 Edje_Real_Part *rp;
2001
2002 rp = ed->table_parts[i];
2003 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
2004 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
2005 (rp->typedata.swallow)) &&
2006 (rp->typedata.swallow->swallowed_object))
2007 efl_gfx_size_class_del(rp->typedata.swallow->swallowed_object, size_class);
2008 }
2009
2010 efl_observable_observers_update(_edje_size_class_member, size_class, NULL);
2011 }
2012
2013 typedef struct _Edje_File_Size_Class_Iterator Edje_File_Size_Class_Iterator;
2014 struct _Edje_File_Size_Class_Iterator
2015 {
2016 Edje_Active_Size_Class_Iterator it;
2017 Edje_File *edf;
2018 };
2019
2020 static Eina_Bool
_edje_mmap_size_class_iterator_next(Eina_Iterator * it,void ** data)2021 _edje_mmap_size_class_iterator_next(Eina_Iterator *it, void **data)
2022 {
2023 Edje_File_Size_Class_Iterator *et = (void *)it;
2024 Eina_Hash_Tuple *tuple = NULL;
2025 Edje_Size_Class *sc = NULL;
2026
2027 if (!eina_iterator_next(et->it.classes, (void **)&tuple)) return EINA_FALSE;
2028 if (!tuple) return EINA_FALSE;
2029
2030 sc = tuple->data;
2031
2032 et->it.sc = *sc;
2033
2034 *data = &et->it.sc;
2035 return EINA_TRUE;
2036 }
2037
2038 static void *
_edje_mmap_size_class_iterator_container(Eina_Iterator * it)2039 _edje_mmap_size_class_iterator_container(Eina_Iterator *it)
2040 {
2041 Edje_File_Size_Class_Iterator *et = (void *)it;
2042
2043 return et->edf->f;
2044 }
2045
2046 static void
_edje_mmap_size_class_iterator_free(Eina_Iterator * it)2047 _edje_mmap_size_class_iterator_free(Eina_Iterator *it)
2048 {
2049 Edje_File_Size_Class_Iterator *et = (void *)it;
2050
2051 eina_iterator_free(et->it.classes);
2052 _edje_cache_file_unref(et->edf);
2053 EINA_MAGIC_SET(&et->it.iterator, 0);
2054 free(et);
2055 }
2056
2057 EAPI Eina_Iterator *
edje_mmap_size_class_iterator_new(Eina_File * f)2058 edje_mmap_size_class_iterator_new(Eina_File *f)
2059 {
2060 Edje_File_Size_Class_Iterator *it;
2061 Edje_File *edf;
2062 int error_ret;
2063
2064 edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL);
2065 if (!edf) return NULL;
2066
2067 it = calloc(1, sizeof (Edje_File_Size_Class_Iterator));
2068 if (!it) goto on_error;
2069
2070 EINA_MAGIC_SET(&it->it.iterator, EINA_MAGIC_ITERATOR);
2071 it->edf = edf;
2072 it->it.classes = eina_hash_iterator_tuple_new(edf->size_hash);
2073
2074 it->it.iterator.version = EINA_ITERATOR_VERSION;
2075 it->it.iterator.next = _edje_mmap_size_class_iterator_next;
2076 it->it.iterator.get_container = _edje_mmap_size_class_iterator_container;
2077 it->it.iterator.free = _edje_mmap_size_class_iterator_free;
2078
2079 return &it->it.iterator;
2080
2081 on_error:
2082 _edje_cache_file_unref(edf);
2083 return NULL;
2084 }
2085
2086 /* Legacy API: exposes internal object. Easy to abuse. */
2087 EAPI const Evas_Object *
edje_object_part_object_get(const Eo * obj,const char * part)2088 edje_object_part_object_get(const Eo *obj, const char *part)
2089 {
2090 Edje_Real_Part *rp;
2091 Edje *ed;
2092
2093 ed = _edje_fetch(obj);
2094 if ((!ed) || (!part)) return NULL;
2095
2096 /* Need to recalc before providing the object. */
2097 if (!ed->freeze) EDJE_RECALC_DO(ed);
2098
2099 rp = _edje_real_part_recursive_get(&ed, part);
2100 if (!rp) return NULL;
2101
2102 return rp->object;
2103 }
2104
2105 EAPI void
edje_object_item_provider_set(Edje_Object * obj,Edje_Item_Provider_Cb func,void * data)2106 edje_object_item_provider_set(Edje_Object *obj, Edje_Item_Provider_Cb func, void *data)
2107 {
2108 Edje *ed = _edje_fetch(obj);
2109 if (!ed) return;
2110 ed->item_provider.func = func;
2111 ed->item_provider.data = data;
2112 }
2113
2114 EAPI void
edje_object_text_change_cb_set(Eo * obj,Edje_Text_Change_Cb func,void * data)2115 edje_object_text_change_cb_set(Eo *obj, Edje_Text_Change_Cb func, void *data)
2116 {
2117 unsigned short i;
2118 Edje *ed;
2119
2120 ed = _edje_fetch(obj);
2121 if (!ed) return;
2122 ed->text_change.func = func;
2123 ed->text_change.data = data;
2124
2125 for (i = 0; i < ed->table_parts_size; i++)
2126 {
2127 Edje_Real_Part *rp;
2128
2129 rp = ed->table_parts[i];
2130 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
2131 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
2132 (rp->typedata.swallow)) &&
2133 (rp->typedata.swallow->swallowed_object))
2134 edje_object_text_change_cb_set(rp->typedata.swallow->swallowed_object, func, data);
2135 }
2136 }
2137
2138 Eina_Bool
_edje_object_part_text_raw_generic_set(Edje * ed,Evas_Object * obj,Edje_Real_Part * rp,const char * part,const char * text,Eina_Bool set_markup,Eina_Bool legacy)2139 _edje_object_part_text_raw_generic_set(Edje *ed, Evas_Object *obj, Edje_Real_Part *rp, const char *part, const char *text, Eina_Bool set_markup, Eina_Bool legacy)
2140 {
2141 if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2142 (!rp->typedata.text)) return EINA_TRUE;
2143 if ((!rp->typedata.text->text) && (!text))
2144 return EINA_TRUE; /* nothing to do, no error */
2145 if ((rp->typedata.text->text) && (text) &&
2146 (!strcmp(rp->typedata.text->text, text)))
2147 return EINA_TRUE; /* nothing to do, no error */
2148 if (rp->typedata.text->text)
2149 {
2150 eina_stringshare_del(rp->typedata.text->text);
2151 rp->typedata.text->text = NULL;
2152 }
2153 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2154 _edje_entry_text_markup_set(rp, text);
2155 else
2156 if (text)
2157 {
2158 if (legacy || (rp->part->type == EDJE_PART_TYPE_TEXT) || set_markup)
2159 {
2160 rp->typedata.text->text = eina_stringshare_add(text);
2161 }
2162 else // !legacy && (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
2163 // && !set_markup
2164 {
2165 char *mkup;
2166 mkup = efl_text_markup_util_text_to_markup(
2167 text);
2168 rp->typedata.text->text = eina_stringshare_add(mkup);
2169 free(mkup);
2170 }
2171 }
2172 ed->dirty = EINA_TRUE;
2173 ed->recalc_call = EINA_TRUE;
2174 ed->recalc_hints = EINA_TRUE;
2175 #ifdef EDJE_CALC_CACHE
2176 rp->invalidate = EINA_TRUE;
2177 #endif
2178 _edje_recalc(ed);
2179 if (ed->text_change.func)
2180 ed->text_change.func(ed->text_change.data, obj, part);
2181 edje_object_signal_emit(ed->obj, "edje,text,changed", "edje");
2182
2183 return EINA_TRUE;
2184 }
2185
2186 Eina_Bool
_edje_object_part_text_raw_set(Edje * ed,Evas_Object * obj,Edje_Real_Part * rp,const char * part,const char * text)2187 _edje_object_part_text_raw_set(Edje *ed, Evas_Object *obj, Edje_Real_Part *rp, const char *part, const char *text)
2188 {
2189 return _edje_object_part_text_raw_generic_set(ed, obj, rp, part, text,
2190 EINA_FALSE, EINA_TRUE);
2191 }
2192
2193 Edje_User_Defined *
_edje_user_text_style_definition_fetch(Edje * ed,const char * part)2194 _edje_user_text_style_definition_fetch(Edje *ed, const char *part)
2195 {
2196 Edje_User_Defined *eud;
2197 Eina_List *l, *ll;
2198
2199 l = eina_hash_find(ed->user_defined, part);
2200 EINA_LIST_FOREACH(l, ll, eud)
2201 if (eud->type == EDJE_USER_TEXT_STYLE) break;
2202
2203 if (!eud)
2204 {
2205 eud = _edje_user_definition_new(EDJE_USER_TEXT_STYLE, part, ed);
2206 if (!eud) return NULL;
2207 eud->u.text_style.types = EDJE_PART_TEXT_PROP_NONE;
2208 eud->u.text_style.props = NULL;
2209 }
2210
2211 return eud;
2212 }
2213
2214 Edje_User_Defined *
_edje_user_text_expand_definition_fetch(Edje * ed,const char * part)2215 _edje_user_text_expand_definition_fetch(Edje *ed, const char *part)
2216 {
2217 Edje_User_Defined *eud;
2218 Eina_List *l, *ll;
2219
2220 l = eina_hash_find(ed->user_defined, part);
2221 EINA_LIST_FOREACH(l, ll, eud)
2222 if (eud->type == EDJE_USER_TEXT_EXPAND) break;
2223
2224 if (!eud)
2225 {
2226 eud = _edje_user_definition_new(EDJE_USER_TEXT_EXPAND, part, ed);
2227 if (!eud) return NULL;
2228 eud->u.text_expand.expand = EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_NONE;
2229 }
2230
2231 return eud;
2232 }
2233
2234 void
_edje_user_define_string(Edje * ed,const char * part,const char * raw_text,Edje_Text_Type type)2235 _edje_user_define_string(Edje *ed, const char *part, const char *raw_text, Edje_Text_Type type)
2236 {
2237 /* NOTE: This one is tricky, text is referenced in rp->typedata.text->text for the life of the
2238 rp. So on edje_object_file_set, we should first ref it, before destroying the old
2239 layout. */
2240 Edje_User_Defined *eud;
2241 Eina_List *l, *ll;
2242
2243 l = eina_hash_find(ed->user_defined, part);
2244 EINA_LIST_FOREACH(l, ll, eud)
2245 if (eud->type == EDJE_USER_STRING)
2246 {
2247 if (!raw_text)
2248 {
2249 _edje_user_definition_free(eud);
2250 return;
2251 }
2252 eud->u.string.text = raw_text;
2253 eud->u.string.type = type;
2254 return;
2255 }
2256
2257 eud = _edje_user_definition_new(EDJE_USER_STRING, part, ed);
2258 if (!eud) return;
2259 eud->u.string.text = raw_text;
2260 eud->u.string.type = type;
2261 }
2262
2263 Eina_Bool
_edje_efl_text_text_set(Eo * obj,Edje * ed,const char * part,const char * text,Eina_Bool legacy,Eina_Bool set_markup)2264 _edje_efl_text_text_set(Eo *obj, Edje *ed, const char *part, const char *text,
2265 Eina_Bool legacy, Eina_Bool set_markup)
2266 {
2267 Edje_Real_Part *rp;
2268 Eina_Bool int_ret;
2269
2270 if ((!ed) || (!part)) return EINA_FALSE;
2271 if ((!ed->file) && (!legacy))
2272 {
2273 _edje_user_define_string(ed, part, eina_stringshare_add(text),
2274 set_markup ? EDJE_TEXT_TYPE_MARKUP : EDJE_TEXT_TYPE_NORMAL);
2275 return EINA_TRUE;
2276 }
2277 rp = _edje_real_part_recursive_get(&ed, part);
2278 if (!rp) return EINA_FALSE;
2279 if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
2280 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE;
2281 if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2282 (!rp->typedata.text))
2283 {
2284 return EINA_TRUE;
2285 }
2286 int_ret = _edje_object_part_text_raw_generic_set(ed, obj, rp, part, text,
2287 set_markup, legacy);
2288 _edje_user_define_string(ed, part, rp->typedata.text->text,
2289 set_markup ? EDJE_TEXT_TYPE_MARKUP : EDJE_TEXT_TYPE_NORMAL);
2290 return int_ret;
2291 }
2292
2293 const char *
_edje_efl_text_text_get(const Eo * obj EINA_UNUSED,Edje * ed,const char * part,Eina_Bool legacy,Eina_Bool get_markup)2294 _edje_efl_text_text_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *part,
2295 Eina_Bool legacy, Eina_Bool get_markup)
2296 {
2297 Edje_Real_Part *rp;
2298
2299 if ((!ed) || (!part)) return NULL;
2300
2301 rp = _edje_real_part_recursive_get(&ed, part);
2302 if (!rp) return NULL;
2303 if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2304 (!rp->typedata.text)) return NULL;
2305 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2306 {
2307 return _edje_entry_text_get(rp);
2308 }
2309 else
2310 {
2311 if (rp->part->type == EDJE_PART_TYPE_TEXT)
2312 {
2313 Edje_Part_Description_Text *desc;
2314 if (rp->typedata.text->text)
2315 return rp->typedata.text->text;
2316 else
2317 {
2318 desc = (Edje_Part_Description_Text *) rp->chosen_description;
2319 if (desc->text.text.translated)
2320 return desc->text.text.translated;
2321 else
2322 return desc->text.text.str;
2323 }
2324 }
2325 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
2326 {
2327 const char *entry;
2328 if (legacy)
2329 {
2330 if (rp->typedata.text->text)
2331 {
2332 entry = rp->typedata.text->text;
2333 }
2334 else
2335 {
2336 #ifdef EDJE_CALC_CACHE
2337 if (rp->invalidate || ed->all_part_change)
2338 #else
2339 if (ed->dirty)
2340 #endif
2341 EDJE_RECALC_DO(ed);
2342 entry = evas_object_textblock_text_markup_get(rp->object);
2343 }
2344 }
2345 else
2346 {
2347 if (get_markup)
2348 {
2349 #ifdef EDJE_CALC_CACHE
2350 if (rp->invalidate || ed->all_part_change)
2351 #else
2352 if (ed->dirty)
2353 #endif
2354 EDJE_RECALC_DO(ed);
2355 entry = efl_text_markup_get(rp->object);
2356 }
2357 else
2358 {
2359 entry = rp->typedata.text->text;
2360 }
2361 }
2362
2363 return entry;
2364 }
2365 }
2366
2367 return NULL;
2368 }
2369
2370 EAPI const char *
edje_object_part_text_selection_get(const Eo * obj,const char * part)2371 edje_object_part_text_selection_get(const Eo *obj, const char *part)
2372 {
2373 Edje_Real_Part *rp;
2374 Edje *ed;
2375
2376 ed = _edje_fetch(obj);
2377
2378 if ((!ed) || (!part)) return NULL;
2379 rp = _edje_real_part_recursive_get(&ed, part);
2380 if (!rp) return NULL;
2381 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2382 return _edje_entry_selection_get(rp);
2383
2384 return NULL;
2385 }
2386
2387 EAPI void
edje_object_part_text_select_none(const Eo * obj,const char * part)2388 edje_object_part_text_select_none(const Eo *obj, const char *part)
2389 {
2390 Edje_Real_Part *rp;
2391 Edje *ed;
2392
2393 ed = _edje_fetch(obj);
2394
2395 if ((!ed) || (!part)) return;
2396 rp = _edje_real_part_recursive_get(&ed, part);
2397 if (!rp) return;
2398 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2399 _edje_entry_select_none(rp);
2400 }
2401
2402 EAPI void
edje_object_part_text_select_all(const Eo * obj,const char * part)2403 edje_object_part_text_select_all(const Eo *obj, const char *part)
2404 {
2405 Edje_Real_Part *rp;
2406 Edje *ed;
2407
2408 ed = _edje_fetch(obj);
2409
2410 if ((!ed) || (!part)) return;
2411 rp = _edje_real_part_recursive_get(&ed, part);
2412 if (!rp) return;
2413 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2414 _edje_entry_select_all(rp);
2415 }
2416
2417 EOLIAN void
_efl_canvas_layout_part_text_cursor_geometry_get(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Evas_Coord * x,Evas_Coord * y,Evas_Coord * w,Evas_Coord * h)2418 _efl_canvas_layout_part_text_cursor_geometry_get(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
2419 {
2420 Edje_Real_Part *rp;
2421
2422 if (x) *x = 0;
2423 if (y) *y = 0;
2424 if (w) *w = 0;
2425 if (h) *h = 0;
2426 if ((!ed) || (!part)) return;
2427 rp = _edje_real_part_recursive_get(&ed, part);
2428 if (!rp) return;
2429 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2430 {
2431 _edje_entry_cursor_geometry_get(rp, x, y, w, h, NULL);
2432 if (x) *x -= ed->x;
2433 if (y) *y -= ed->y;
2434 }
2435 }
2436
2437 EAPI void
edje_object_part_text_select_allow_set(const Eo * obj,const char * part,Eina_Bool allow)2438 edje_object_part_text_select_allow_set(const Eo *obj, const char *part, Eina_Bool allow)
2439 {
2440 Edje_Real_Part *rp;
2441 Edje *ed;
2442
2443 ed = _edje_fetch(obj);
2444
2445 if ((!ed) || (!part)) return;
2446 rp = _edje_real_part_recursive_get(&ed, part);
2447 if (!rp) return;
2448 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2449 _edje_entry_select_allow_set(rp, allow);
2450 }
2451
2452 EAPI void
edje_object_part_text_select_abort(const Eo * obj,const char * part)2453 edje_object_part_text_select_abort(const Eo *obj, const char *part)
2454 {
2455 Edje_Real_Part *rp;
2456 Edje *ed;
2457
2458 ed = _edje_fetch(obj);
2459
2460 if ((!ed) || (!part)) return;
2461 rp = _edje_real_part_recursive_get(&ed, part);
2462 if (!rp) return;
2463 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2464 _edje_entry_select_abort(rp);
2465 }
2466
2467 EAPI void
edje_object_part_text_select_begin(const Eo * obj,const char * part)2468 edje_object_part_text_select_begin(const Eo *obj, const char *part)
2469 {
2470 Edje_Real_Part *rp;
2471 Edje *ed;
2472
2473 ed = _edje_fetch(obj);
2474
2475 if ((!ed) || (!part)) return;
2476 rp = _edje_real_part_recursive_get(&ed, part);
2477 if (!rp) return;
2478 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2479 _edje_entry_select_begin(rp);
2480 }
2481
2482 EAPI void
edje_object_part_text_select_extend(const Eo * obj,const char * part)2483 edje_object_part_text_select_extend(const Eo *obj, const char *part)
2484 {
2485 Edje_Real_Part *rp;
2486 Edje *ed;
2487
2488 ed = _edje_fetch(obj);
2489
2490 if ((!ed) || (!part)) return;
2491 rp = _edje_real_part_recursive_get(&ed, part);
2492 if (!rp) return;
2493 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2494 _edje_entry_select_extend(rp);
2495 }
2496
2497 EOLIAN Eina_Bool
_efl_canvas_layout_part_text_cursor_next(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2498 _efl_canvas_layout_part_text_cursor_next(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2499 {
2500 Edje_Real_Part *rp;
2501
2502 if ((!ed) || (!part)) return EINA_FALSE;
2503 rp = _edje_real_part_recursive_get(&ed, part);
2504 if (!rp) return EINA_FALSE;
2505 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2506 {
2507 return _edje_entry_cursor_next(rp, cur);
2508 }
2509
2510 return EINA_FALSE;
2511 }
2512
2513 EOLIAN Eina_Bool
_efl_canvas_layout_part_text_cursor_prev(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2514 _efl_canvas_layout_part_text_cursor_prev(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2515 {
2516 Edje_Real_Part *rp;
2517
2518 if ((!ed) || (!part)) return EINA_FALSE;
2519 rp = _edje_real_part_recursive_get(&ed, part);
2520 if (!rp) return EINA_FALSE;
2521 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2522 {
2523 return _edje_entry_cursor_prev(rp, cur);
2524 }
2525
2526 return EINA_FALSE;
2527 }
2528
2529 EOLIAN Eina_Bool
_efl_canvas_layout_part_text_cursor_up(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2530 _efl_canvas_layout_part_text_cursor_up(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2531 {
2532 Edje_Real_Part *rp;
2533
2534 if ((!ed) || (!part)) return EINA_FALSE;
2535 rp = _edje_real_part_recursive_get(&ed, part);
2536 if (!rp) return EINA_FALSE;
2537 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2538 {
2539 return _edje_entry_cursor_up(rp, cur);
2540 }
2541
2542 return EINA_FALSE;
2543 }
2544
2545 EOLIAN Eina_Bool
_efl_canvas_layout_part_text_cursor_down(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2546 _efl_canvas_layout_part_text_cursor_down(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2547 {
2548 Edje_Real_Part *rp;
2549
2550 if ((!ed) || (!part)) return EINA_FALSE;
2551 rp = _edje_real_part_recursive_get(&ed, part);
2552 if (!rp) return EINA_FALSE;
2553 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2554 {
2555 return _edje_entry_cursor_down(rp, cur);
2556 }
2557
2558 return EINA_FALSE;
2559 }
2560
2561 EOLIAN void
_efl_canvas_layout_part_text_cursor_begin_set(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2562 _efl_canvas_layout_part_text_cursor_begin_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2563 {
2564 Edje_Real_Part *rp;
2565
2566 if ((!ed) || (!part)) return;
2567 rp = _edje_real_part_recursive_get(&ed, part);
2568 if (!rp) return;
2569 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2570 {
2571 _edje_entry_cursor_begin(rp, cur);
2572 }
2573 }
2574
2575 EOLIAN void
_efl_canvas_layout_part_text_cursor_end_set(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2576 _efl_canvas_layout_part_text_cursor_end_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2577 {
2578 Edje_Real_Part *rp;
2579
2580 if ((!ed) || (!part)) return;
2581 rp = _edje_real_part_recursive_get(&ed, part);
2582 if (!rp) return;
2583 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2584 {
2585 _edje_entry_cursor_end(rp, cur);
2586 }
2587 }
2588
2589 EOLIAN void
_efl_canvas_layout_part_text_cursor_copy(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor src,Edje_Cursor dst)2590 _efl_canvas_layout_part_text_cursor_copy(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor src, Edje_Cursor dst)
2591 {
2592 Edje_Real_Part *rp;
2593
2594 if ((!ed) || (!part)) return;
2595 rp = _edje_real_part_recursive_get(&ed, part);
2596 if (!rp) return;
2597 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2598 {
2599 _edje_entry_cursor_copy(rp, src, dst);
2600 }
2601 }
2602
2603 EOLIAN void
_efl_canvas_layout_part_text_cursor_line_begin_set(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2604 _efl_canvas_layout_part_text_cursor_line_begin_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2605 {
2606 Edje_Real_Part *rp;
2607
2608 if ((!ed) || (!part)) return;
2609 rp = _edje_real_part_recursive_get(&ed, part);
2610 if (!rp) return;
2611 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2612 {
2613 _edje_entry_cursor_line_begin(rp, cur);
2614 }
2615 }
2616
2617 EOLIAN void
_efl_canvas_layout_part_text_cursor_line_end_set(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2618 _efl_canvas_layout_part_text_cursor_line_end_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2619 {
2620 Edje_Real_Part *rp;
2621
2622 if ((!ed) || (!part)) return;
2623 rp = _edje_real_part_recursive_get(&ed, part);
2624 if (!rp) return;
2625 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2626 {
2627 _edje_entry_cursor_line_end(rp, cur);
2628 }
2629 }
2630
2631 EOLIAN Eina_Bool
_efl_canvas_layout_part_text_cursor_coord_set(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur,Evas_Coord x,Evas_Coord y)2632 _efl_canvas_layout_part_text_cursor_coord_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur, Evas_Coord x, Evas_Coord y)
2633 {
2634 Edje_Real_Part *rp;
2635
2636 if ((!ed) || (!part)) return EINA_FALSE;
2637 rp = _edje_real_part_recursive_get(&ed, part);
2638 if (!rp) return EINA_FALSE;
2639 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2640 {
2641 return _edje_entry_cursor_coord_set(rp, cur, x, y);
2642 }
2643
2644 return EINA_FALSE;
2645 }
2646
2647 EOLIAN void
_efl_canvas_layout_part_text_cursor_pos_set(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur,int pos)2648 _efl_canvas_layout_part_text_cursor_pos_set(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur, int pos)
2649 {
2650 Edje_Real_Part *rp;
2651
2652 if ((!ed) || (!part)) return;
2653 rp = _edje_real_part_recursive_get(&ed, part);
2654 if (!rp) return;
2655 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2656 {
2657 _edje_entry_cursor_pos_set(rp, cur, pos);
2658 }
2659 }
2660
2661 EOLIAN int
_efl_canvas_layout_part_text_cursor_pos_get(Eo * obj EINA_UNUSED,Edje * ed,const char * part,Edje_Cursor cur)2662 _efl_canvas_layout_part_text_cursor_pos_get(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Edje_Cursor cur)
2663 {
2664 int ret;
2665 Edje_Real_Part *rp;
2666 ret = 0;
2667
2668 if ((!ed) || (!part)) return ret;
2669 rp = _edje_real_part_recursive_get(&ed, part);
2670 if (!rp) return ret;
2671 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2672 {
2673 ret = _edje_entry_cursor_pos_get(rp, cur);
2674 }
2675
2676 return ret;
2677 }
2678
2679 EAPI void *
edje_object_part_text_imf_context_get(const Eo * obj,const char * part)2680 edje_object_part_text_imf_context_get(const Eo *obj, const char *part)
2681 {
2682 Edje_Real_Part *rp;
2683 Edje *ed;
2684
2685 ed = _edje_fetch(obj);
2686
2687 if ((!ed) || (!part)) return NULL;
2688
2689 rp = _edje_real_part_recursive_get(&ed, (char *)part);
2690 if (!rp) return NULL;
2691
2692 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2693 return _edje_entry_imf_context_get(rp);
2694
2695 return NULL;
2696 }
2697
2698 EAPI void
edje_object_part_text_imf_context_reset(const Eo * obj,const char * part)2699 edje_object_part_text_imf_context_reset(const Eo *obj, const char *part)
2700 {
2701 Edje_Real_Part *rp;
2702 Edje *ed;
2703
2704 ed = _edje_fetch(obj);
2705
2706 if ((!ed) || (!part)) return;
2707 rp = _edje_real_part_recursive_get(&ed, part);
2708 if (!rp) return;
2709 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2710 {
2711 _edje_entry_imf_context_reset(rp);
2712 }
2713 }
2714
2715 EAPI void
edje_object_part_text_input_panel_layout_set(Eo * obj,const char * part,Edje_Input_Panel_Layout layout)2716 edje_object_part_text_input_panel_layout_set(Eo *obj, const char *part, Edje_Input_Panel_Layout layout)
2717 {
2718 Edje_Real_Part *rp;
2719 Edje *ed;
2720
2721 ed = _edje_fetch(obj);
2722
2723 if ((!ed) || (!part)) return;
2724 rp = _edje_real_part_recursive_get(&ed, part);
2725 if (!rp) return;
2726 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2727 {
2728 _edje_entry_input_panel_layout_set(rp, layout);
2729 }
2730 }
2731
2732 EAPI Edje_Input_Panel_Layout
edje_object_part_text_input_panel_layout_get(const Eo * obj,const char * part)2733 edje_object_part_text_input_panel_layout_get(const Eo *obj, const char *part)
2734 {
2735 Edje_Input_Panel_Layout ret;
2736 Edje_Real_Part *rp;
2737 ret = EDJE_INPUT_PANEL_LAYOUT_INVALID;
2738 Edje *ed;
2739
2740 ed = _edje_fetch(obj);
2741
2742 if ((!ed) || (!part)) return ret;
2743 rp = _edje_real_part_recursive_get(&ed, part);
2744 if (!rp) return ret;
2745 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2746 {
2747 ret = _edje_entry_input_panel_layout_get(rp);
2748 }
2749
2750 return ret;
2751 }
2752
2753 EAPI void
edje_object_part_text_input_panel_layout_variation_set(Eo * obj,const char * part,int variation)2754 edje_object_part_text_input_panel_layout_variation_set(Eo *obj, const char *part, int variation)
2755 {
2756 Edje_Real_Part *rp;
2757 Edje *ed;
2758
2759 ed = _edje_fetch(obj);
2760
2761 if ((!ed) || (!part)) return;
2762 rp = _edje_real_part_recursive_get(&ed, part);
2763 if (!rp) return;
2764 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2765 {
2766 _edje_entry_input_panel_layout_variation_set(rp, variation);
2767 }
2768 }
2769
2770 EAPI int
edje_object_part_text_input_panel_layout_variation_get(const Eo * obj,const char * part)2771 edje_object_part_text_input_panel_layout_variation_get(const Eo *obj, const char *part)
2772 {
2773 int r;
2774
2775 Edje_Real_Part *rp;
2776 Edje *ed;
2777
2778 ed = _edje_fetch(obj);
2779
2780 r = 0;
2781 if ((!ed) || (!part)) return r;
2782 rp = _edje_real_part_recursive_get(&ed, part);
2783 if (!rp) return r;
2784 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2785 {
2786 r = _edje_entry_input_panel_layout_variation_get(rp);
2787 }
2788 return r;
2789 }
2790
2791 EAPI void
edje_object_part_text_autocapital_type_set(Eo * obj,const char * part,Edje_Text_Autocapital_Type autocapital_type)2792 edje_object_part_text_autocapital_type_set(Eo *obj, const char *part, Edje_Text_Autocapital_Type autocapital_type)
2793 {
2794 Edje_Real_Part *rp;
2795 Edje *ed;
2796
2797 ed = _edje_fetch(obj);
2798 if ((!ed) || (!part)) return;
2799 rp = _edje_real_part_recursive_get(&ed, part);
2800 if (!rp) return;
2801 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2802 {
2803 _edje_entry_autocapital_type_set(rp, autocapital_type);
2804 }
2805 }
2806
2807 EAPI Edje_Text_Autocapital_Type
edje_object_part_text_autocapital_type_get(const Eo * obj,const char * part)2808 edje_object_part_text_autocapital_type_get(const Eo *obj, const char *part)
2809 {
2810 Edje_Text_Autocapital_Type ret;
2811 Edje_Real_Part *rp;
2812 ret = EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2813 Edje *ed;
2814
2815 ed = _edje_fetch(obj);
2816
2817 if ((!ed) || (!part)) return ret;
2818 rp = _edje_real_part_recursive_get(&ed, part);
2819 if (!rp) return ret;
2820 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2821 {
2822 ret = _edje_entry_autocapital_type_get(rp);
2823 }
2824
2825 return ret;
2826 }
2827
2828 EAPI void
edje_object_part_text_prediction_allow_set(Eo * obj,const char * part,Eina_Bool prediction)2829 edje_object_part_text_prediction_allow_set(Eo *obj, const char *part, Eina_Bool prediction)
2830 {
2831 Edje_Real_Part *rp;
2832 Edje *ed;
2833
2834 ed = _edje_fetch(obj);
2835
2836 if ((!ed) || (!part)) return;
2837 rp = _edje_real_part_recursive_get(&ed, part);
2838 if (!rp) return;
2839 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2840 {
2841 _edje_entry_prediction_allow_set(rp, prediction);
2842 }
2843 }
2844
2845 EAPI Eina_Bool
edje_object_part_text_prediction_allow_get(const Eo * obj,const char * part)2846 edje_object_part_text_prediction_allow_get(const Eo *obj, const char *part)
2847 {
2848 Eina_Bool ret;
2849 Edje_Real_Part *rp;
2850 ret = EINA_FALSE;
2851 Edje *ed;
2852
2853 ed = _edje_fetch(obj);
2854
2855 if ((!ed) || (!part)) return ret;
2856 rp = _edje_real_part_recursive_get(&ed, part);
2857 if (!rp) return ret;
2858 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2859 {
2860 ret = _edje_entry_prediction_allow_get(rp);
2861 }
2862
2863 return ret;
2864 }
2865
2866 EAPI void
edje_object_part_text_input_hint_set(Eo * obj,const char * part,Edje_Input_Hints input_hints)2867 edje_object_part_text_input_hint_set(Eo *obj, const char *part, Edje_Input_Hints input_hints)
2868 {
2869 Edje_Real_Part *rp;
2870 Edje *ed;
2871
2872 ed = _edje_fetch(obj);
2873
2874 if ((!ed) || (!part)) return;
2875 rp = _edje_real_part_recursive_get(&ed, part);
2876 if (!rp) return;
2877 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2878 {
2879 _edje_entry_input_hint_set(rp, input_hints);
2880 }
2881 }
2882
2883 EAPI Edje_Input_Hints
edje_object_part_text_input_hint_get(const Eo * obj,const char * part)2884 edje_object_part_text_input_hint_get(const Eo *obj, const char *part)
2885 {
2886 Edje_Real_Part *rp;
2887 Edje *ed;
2888
2889 ed = _edje_fetch(obj);
2890
2891 if ((!ed) || (!part)) return EINA_FALSE;
2892 rp = _edje_real_part_recursive_get(&ed, part);
2893 if (!rp) return EINA_FALSE;
2894 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2895 {
2896 return _edje_entry_input_hint_get(rp);
2897 }
2898 return EINA_FALSE;
2899 }
2900
2901 EAPI void
edje_object_part_text_input_panel_enabled_set(Eo * obj,const char * part,Eina_Bool enabled)2902 edje_object_part_text_input_panel_enabled_set(Eo *obj, const char *part, Eina_Bool enabled)
2903 {
2904 Edje_Real_Part *rp;
2905 Edje *ed;
2906
2907 ed = _edje_fetch(obj);
2908
2909 if ((!ed) || (!part)) return;
2910 rp = _edje_real_part_recursive_get(&ed, part);
2911 if (!rp) return;
2912 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2913 {
2914 _edje_entry_input_panel_enabled_set(rp, enabled);
2915 }
2916 }
2917
2918 EAPI Eina_Bool
edje_object_part_text_input_panel_enabled_get(const Eo * obj,const char * part)2919 edje_object_part_text_input_panel_enabled_get(const Eo *obj, const char *part)
2920 {
2921 Eina_Bool ret;
2922 Edje_Real_Part *rp;
2923 ret = EINA_FALSE;
2924 Edje *ed;
2925
2926 ed = _edje_fetch(obj);
2927
2928 if ((!ed) || (!part)) return ret;
2929 rp = _edje_real_part_recursive_get(&ed, part);
2930 if (!rp) return ret;
2931 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2932 {
2933 ret = _edje_entry_input_panel_enabled_get(rp);
2934 }
2935
2936 return ret;
2937 }
2938
2939 EAPI void
edje_object_part_text_input_panel_show(const Eo * obj,const char * part)2940 edje_object_part_text_input_panel_show(const Eo *obj, const char *part)
2941 {
2942 Edje_Real_Part *rp;
2943 Edje *ed;
2944
2945 ed = _edje_fetch(obj);
2946
2947 if ((!ed) || (!part)) return;
2948 rp = _edje_real_part_recursive_get(&ed, part);
2949 if (!rp) return;
2950 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2951 _edje_entry_input_panel_show(rp);
2952 }
2953
2954 EAPI void
edje_object_part_text_input_panel_hide(const Eo * obj,const char * part)2955 edje_object_part_text_input_panel_hide(const Eo *obj, const char *part)
2956 {
2957 Edje_Real_Part *rp;
2958 Edje *ed;
2959
2960 ed = _edje_fetch(obj);
2961
2962 if ((!ed) || (!part)) return;
2963 rp = _edje_real_part_recursive_get(&ed, part);
2964 if (!rp) return;
2965 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2966 _edje_entry_input_panel_hide(rp);
2967 }
2968
2969 EAPI void
edje_object_part_text_input_panel_language_set(Eo * obj,const char * part,Edje_Input_Panel_Lang lang)2970 edje_object_part_text_input_panel_language_set(Eo *obj, const char *part, Edje_Input_Panel_Lang lang)
2971 {
2972 Edje_Real_Part *rp;
2973 Edje *ed;
2974
2975 ed = _edje_fetch(obj);
2976
2977 if ((!ed) || (!part)) return;
2978 rp = _edje_real_part_recursive_get(&ed, part);
2979 if (!rp) return;
2980 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
2981 {
2982 _edje_entry_input_panel_language_set(rp, lang);
2983 }
2984 }
2985
2986 EAPI Edje_Input_Panel_Lang
edje_object_part_text_input_panel_language_get(const Eo * obj,const char * part)2987 edje_object_part_text_input_panel_language_get(const Eo *obj, const char *part)
2988 {
2989 Edje_Input_Panel_Lang ret;
2990 Edje_Real_Part *rp;
2991 ret = EDJE_INPUT_PANEL_LANG_AUTOMATIC;
2992 Edje *ed;
2993
2994 ed = _edje_fetch(obj);
2995
2996 if ((!ed) || (!part)) return ret;
2997 rp = _edje_real_part_recursive_get(&ed, part);
2998 if (!rp) return ret;
2999 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3000 {
3001 ret = _edje_entry_input_panel_language_get(rp);
3002 }
3003
3004 return ret;
3005 }
3006
3007 EAPI void
edje_object_part_text_input_panel_imdata_set(Eo * obj,const char * part,const void * data,int len)3008 edje_object_part_text_input_panel_imdata_set(Eo *obj, const char *part, const void *data, int len)
3009 {
3010 Edje_Real_Part *rp;
3011 Edje *ed;
3012
3013 ed = _edje_fetch(obj);
3014
3015 if ((!ed) || (!part)) return;
3016 rp = _edje_real_part_recursive_get(&ed, part);
3017 if (!rp) return;
3018 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3019 {
3020 _edje_entry_input_panel_imdata_set(rp, data, len);
3021 }
3022 }
3023
3024 EAPI void
edje_object_part_text_input_panel_imdata_get(const Eo * obj,const char * part,void * data,int * len)3025 edje_object_part_text_input_panel_imdata_get(const Eo *obj, const char *part, void *data, int *len)
3026 {
3027 Edje_Real_Part *rp;
3028 Edje *ed;
3029
3030 ed = _edje_fetch(obj);
3031
3032 if ((!ed) || (!part)) return;
3033 rp = _edje_real_part_recursive_get(&ed, part);
3034 if (!rp) return;
3035 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3036 {
3037 _edje_entry_input_panel_imdata_get(rp, data, len);
3038 }
3039 }
3040
3041 EAPI void
edje_object_part_text_input_panel_return_key_type_set(Eo * obj,const char * part,Edje_Input_Panel_Return_Key_Type return_key_type)3042 edje_object_part_text_input_panel_return_key_type_set(Eo *obj, const char *part, Edje_Input_Panel_Return_Key_Type return_key_type)
3043 {
3044 Edje_Real_Part *rp;
3045 Edje *ed;
3046
3047 ed = _edje_fetch(obj);
3048
3049 if ((!ed) || (!part)) return;
3050 rp = _edje_real_part_recursive_get(&ed, part);
3051 if (!rp) return;
3052 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3053 {
3054 _edje_entry_input_panel_return_key_type_set(rp, return_key_type);
3055 }
3056 }
3057
3058 EAPI Edje_Input_Panel_Return_Key_Type
edje_object_part_text_input_panel_return_key_type_get(const Eo * obj,const char * part)3059 edje_object_part_text_input_panel_return_key_type_get(const Eo *obj, const char *part)
3060 {
3061 Edje_Input_Panel_Return_Key_Type ret;
3062 Edje_Real_Part *rp;
3063 ret = EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3064 Edje *ed;
3065
3066 ed = _edje_fetch(obj);
3067
3068 if ((!ed) || (!part)) return ret;
3069 rp = _edje_real_part_recursive_get(&ed, part);
3070 if (!rp) return ret;
3071 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3072 {
3073 ret = _edje_entry_input_panel_return_key_type_get(rp);
3074 }
3075
3076 return ret;
3077 }
3078
3079 EAPI void
edje_object_part_text_input_panel_return_key_disabled_set(Eo * obj,const char * part,Eina_Bool disabled)3080 edje_object_part_text_input_panel_return_key_disabled_set(Eo *obj, const char *part, Eina_Bool disabled)
3081 {
3082 Edje_Real_Part *rp;
3083 Edje *ed;
3084
3085 ed = _edje_fetch(obj);
3086
3087 if ((!ed) || (!part)) return;
3088 rp = _edje_real_part_recursive_get(&ed, part);
3089 if (!rp) return;
3090 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3091 {
3092 _edje_entry_input_panel_return_key_disabled_set(rp, disabled);
3093 }
3094 }
3095
3096 EAPI Eina_Bool
edje_object_part_text_input_panel_return_key_disabled_get(const Eo * obj,const char * part)3097 edje_object_part_text_input_panel_return_key_disabled_get(const Eo *obj, const char *part)
3098 {
3099 Eina_Bool ret;
3100 Edje_Real_Part *rp;
3101 Edje *ed;
3102
3103 ret = EINA_FALSE;
3104 ed = _edje_fetch(obj);
3105
3106 if ((!ed) || (!part)) return ret;
3107 rp = _edje_real_part_recursive_get(&ed, part);
3108 if (!rp) return ret;
3109 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3110 {
3111 ret = _edje_entry_input_panel_return_key_disabled_get(rp);
3112 }
3113
3114 return ret;
3115 }
3116
3117 EAPI void
edje_object_part_text_input_panel_show_on_demand_set(Eo * obj,const char * part,Eina_Bool ondemand)3118 edje_object_part_text_input_panel_show_on_demand_set(Eo *obj, const char *part, Eina_Bool ondemand)
3119 {
3120 Edje_Real_Part *rp;
3121 Edje *ed;
3122
3123 ed = _edje_fetch(obj);
3124
3125 if ((!ed) || (!part)) return;
3126 rp = _edje_real_part_recursive_get(&ed, part);
3127 if (!rp) return;
3128 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3129 {
3130 _edje_entry_input_panel_show_on_demand_set(rp, ondemand);
3131 }
3132 }
3133
3134 EAPI Eina_Bool
edje_object_part_text_input_panel_show_on_demand_get(const Eo * obj,const char * part)3135 edje_object_part_text_input_panel_show_on_demand_get(const Eo *obj, const char *part)
3136 {
3137 Eina_Bool ret;
3138 Edje_Real_Part *rp;
3139 Edje *ed;
3140
3141 ret = EINA_FALSE;
3142 ed = _edje_fetch(obj);
3143
3144 if ((!ed) || (!part)) return ret;
3145 rp = _edje_real_part_recursive_get(&ed, part);
3146 if (!rp) return ret;
3147 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3148 {
3149 ret = _edje_entry_input_panel_show_on_demand_get(rp);
3150 }
3151
3152 return ret;
3153 }
3154
3155 EAPI void
edje_object_part_text_prediction_hint_set(Eo * obj,const char * part,const char * prediction_hint)3156 edje_object_part_text_prediction_hint_set(Eo *obj, const char *part, const char *prediction_hint)
3157 {
3158 Edje_Real_Part *rp;
3159 Edje *ed;
3160
3161 ed = _edje_fetch(obj);
3162
3163 if ((!ed) || (!part)) return;
3164 rp = _edje_real_part_recursive_get(&ed, part);
3165 if (!rp) return;
3166 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3167 {
3168 _edje_entry_prediction_hint_set(rp, prediction_hint);
3169 }
3170 }
3171
3172 Eina_Bool
_edje_efl_content_content_set(Edje * ed,const char * part,Efl_Gfx_Entity * obj_swallow)3173 _edje_efl_content_content_set(Edje *ed, const char *part, Efl_Gfx_Entity *obj_swallow)
3174 {
3175 Edje_Real_Part *rp, *rpcur;
3176 Edje_User_Defined *eud = NULL;
3177
3178 if ((!ed) || (!part)) return EINA_FALSE;
3179
3180 /* Need to recalc before providing the object. */
3181 // XXX: I guess this is not required, removing for testing purposes
3182 // XXX: uncomment if you see glitches in e17 or others.
3183 // XXX: by Gustavo, January 21th 2009.
3184 // XXX: I got a backtrace with over 30000 calls without this,
3185 // XXX: only with 32px shelves. The problem is probably somewhere else,
3186 // XXX: but until it's found, leave this here.
3187 // XXX: by Sachiel, January 21th 2009, 19:30 UTC
3188 // GFY: I decided to try removing this while optimizing some edc and saw
3189 // SRS: no downside after moderate testing, so I decided to commit it.
3190 // LOL: - zmike, 1 April 2015
3191 //_edje_recalc_do(ed);
3192
3193 rp = _edje_real_part_recursive_get(&ed, part);
3194 rpcur = evas_object_data_get(obj_swallow, "\377 edje.swallowing_part");
3195 if (rpcur)
3196 {
3197 Edje *sed;
3198
3199 /* the object is already swallowed in the requested part */
3200 if (rpcur == rp) return EINA_TRUE;
3201 sed = evas_object_data_get(obj_swallow, ".edje");
3202 if (sed)
3203 {
3204 /* The object is already swallowed somewhere, unswallow it first */
3205 edje_object_part_unswallow(sed->obj, obj_swallow);
3206 }
3207 }
3208
3209 if (!ed->file)
3210 {
3211 eud = _edje_user_definition_new(EDJE_USER_SWALLOW, part, ed);
3212 if (eud)
3213 {
3214 evas_object_event_callback_add(obj_swallow, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
3215 eud->u.swallow.child = obj_swallow;
3216 }
3217 return EINA_TRUE;
3218 }
3219 if (!rp)
3220 {
3221 DBG("cannot swallow part %s: part not exist!", part);
3222 return EINA_FALSE;
3223 }
3224 if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
3225 {
3226 ERR("cannot swallow part %s: not swallow type!", rp->part->name);
3227 return EINA_FALSE;
3228 }
3229 if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
3230 (!rp->typedata.swallow)) return EINA_FALSE;
3231 _edje_real_part_swallow(ed, rp, obj_swallow, EINA_TRUE);
3232
3233 if (rp->typedata.swallow->swallowed_object)
3234 {
3235 eud = _edje_user_definition_new(EDJE_USER_SWALLOW, part, ed);
3236 if (eud)
3237 {
3238 evas_object_event_callback_add(obj_swallow, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
3239 eud->u.swallow.child = obj_swallow;
3240 }
3241 }
3242 if (ed->has_content_change_event_cb)
3243 efl_event_callback_call(ed->obj, EFL_CONTENT_EVENT_CONTENT_CHANGED, obj_swallow);
3244 return EINA_TRUE;
3245 }
3246
3247 EAPI void
edje_extern_object_min_size_set(Evas_Object * obj,Evas_Coord minw,Evas_Coord minh)3248 edje_extern_object_min_size_set(Evas_Object *obj, Evas_Coord minw, Evas_Coord minh)
3249 {
3250 if (!obj) return;
3251
3252 evas_object_size_hint_min_set(obj, minw, minh);
3253 }
3254
3255 EAPI void
edje_extern_object_max_size_set(Evas_Object * obj,Evas_Coord maxw,Evas_Coord maxh)3256 edje_extern_object_max_size_set(Evas_Object *obj, Evas_Coord maxw, Evas_Coord maxh)
3257 {
3258 if (!obj) return;
3259
3260 evas_object_size_hint_max_set(obj, maxw, maxh);
3261 }
3262
3263 EAPI void
edje_extern_object_aspect_set(Evas_Object * obj,Edje_Aspect_Control aspect,Evas_Coord aw,Evas_Coord ah)3264 edje_extern_object_aspect_set(Evas_Object *obj, Edje_Aspect_Control aspect, Evas_Coord aw, Evas_Coord ah)
3265 {
3266 if (!obj) return;
3267 Evas_Aspect_Control asp;
3268
3269 asp = EVAS_ASPECT_CONTROL_NONE;
3270 switch (aspect)
3271 {
3272 case EDJE_ASPECT_CONTROL_NONE: asp = EVAS_ASPECT_CONTROL_NONE; break;
3273
3274 case EDJE_ASPECT_CONTROL_NEITHER: asp = EVAS_ASPECT_CONTROL_NEITHER; break;
3275
3276 case EDJE_ASPECT_CONTROL_HORIZONTAL: asp = EVAS_ASPECT_CONTROL_HORIZONTAL; break;
3277
3278 case EDJE_ASPECT_CONTROL_VERTICAL: asp = EVAS_ASPECT_CONTROL_VERTICAL; break;
3279
3280 case EDJE_ASPECT_CONTROL_BOTH: asp = EVAS_ASPECT_CONTROL_BOTH; break;
3281
3282 default: break;
3283 }
3284 if (aw < 1) aw = 1;
3285 if (ah < 1) ah = 1;
3286 evas_object_size_hint_aspect_set(obj, asp, aw, ah);
3287 }
3288
3289 struct edje_box_layout_builtin
3290 {
3291 const char *name;
3292 Evas_Object_Box_Layout cb;
3293 };
3294
3295 static Evas_Object_Box_Layout
_edje_box_layout_builtin_find(const char * name)3296 _edje_box_layout_builtin_find(const char *name)
3297 {
3298 const struct edje_box_layout_builtin _edje_box_layout_builtin[] = {
3299 {"horizontal", evas_object_box_layout_horizontal},
3300 {"horizontal_flow", evas_object_box_layout_flow_horizontal},
3301 {"horizontal_homogeneous", evas_object_box_layout_homogeneous_horizontal},
3302 {"horizontal_max", evas_object_box_layout_homogeneous_max_size_horizontal},
3303 {"stack", evas_object_box_layout_stack},
3304 {"vertical", evas_object_box_layout_vertical},
3305 {"vertical_flow", evas_object_box_layout_flow_vertical},
3306 {"vertical_homogeneous", evas_object_box_layout_homogeneous_vertical},
3307 {"vertical_max", evas_object_box_layout_homogeneous_max_size_vertical},
3308 {NULL, NULL}
3309 };
3310 const struct edje_box_layout_builtin *base;
3311
3312 switch (name[0])
3313 {
3314 case 'h':
3315 base = _edje_box_layout_builtin + 0;
3316 break;
3317
3318 case 's':
3319 base = _edje_box_layout_builtin + 4;
3320 break;
3321
3322 case 'v':
3323 base = _edje_box_layout_builtin + 5;
3324 break;
3325
3326 default:
3327 return NULL;
3328 }
3329
3330 for (; (base->name) && (base->name[0] == name[0]); base++)
3331 if (strcmp(base->name, name) == 0)
3332 return base->cb;
3333
3334 return NULL;
3335 }
3336
3337 static Eina_Rbtree_Direction
_edje_box_layout_part_external_node_cmp(const Eina_Rbtree * left,const Eina_Rbtree * right,void * data EINA_UNUSED)3338 _edje_box_layout_part_external_node_cmp(const Eina_Rbtree *left, const Eina_Rbtree *right, void *data EINA_UNUSED)
3339 {
3340 Edje_Box_Layout *l = (Edje_Box_Layout *)left;
3341 Edje_Box_Layout *r = (Edje_Box_Layout *)right;
3342
3343 if (strcmp(l->name, r->name) < 0)
3344 return EINA_RBTREE_RIGHT;
3345 else
3346 return EINA_RBTREE_LEFT;
3347 }
3348
3349 static int
_edje_box_layout_part_external_find_cmp(const Eina_Rbtree * node,const void * key,int length EINA_UNUSED,void * data EINA_UNUSED)3350 _edje_box_layout_part_external_find_cmp(const Eina_Rbtree *node, const void *key, int length EINA_UNUSED, void *data EINA_UNUSED)
3351 {
3352 Edje_Box_Layout *l = (Edje_Box_Layout *)node;
3353 return strcmp(key, l->name);
3354 }
3355
3356 static Edje_Box_Layout *
_edje_box_layout_part_external_find(const char * name)3357 _edje_box_layout_part_external_find(const char *name)
3358 {
3359 return (Edje_Box_Layout *)eina_rbtree_inline_lookup
3360 (_edje_box_layout_registry, name, 0, _edje_box_layout_part_external_find_cmp,
3361 NULL);
3362 }
3363
3364 EAPI Eina_Bool
edje_object_part_text_prediction_hint_hash_set(Eo * obj,const char * part,const char * key,const char * value)3365 edje_object_part_text_prediction_hint_hash_set(Eo *obj, const char *part, const char *key, const char *value)
3366 {
3367 Edje_Real_Part *rp;
3368 Edje *ed;
3369
3370 ed = _edje_fetch(obj);
3371
3372 if ((!ed) || (!part)) return EINA_FALSE;
3373 rp = _edje_real_part_recursive_get(&ed, part);
3374 if (!rp) return EINA_FALSE;
3375 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3376 {
3377 return _edje_entry_prediction_hint_hash_set(rp, key, value);
3378 }
3379 else
3380 return EINA_FALSE;
3381 }
3382
3383 EAPI Eina_Bool
edje_object_part_text_prediction_hint_hash_del(Eo * obj,const char * part,const char * key)3384 edje_object_part_text_prediction_hint_hash_del(Eo *obj, const char *part, const char *key)
3385 {
3386 Edje_Real_Part *rp;
3387 Edje *ed;
3388
3389 ed = _edje_fetch(obj);
3390
3391 if ((!ed) || (!part)) return EINA_FALSE;
3392 rp = _edje_real_part_recursive_get(&ed, part);
3393 if (!rp) return EINA_FALSE;
3394 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
3395 {
3396 return _edje_entry_prediction_hint_hash_del(rp, key);
3397 }
3398 else
3399 return EINA_FALSE;
3400 }
3401
3402 Eina_Bool
_edje_box_layout_find(const char * name,Evas_Object_Box_Layout * cb,void ** data,void (** free_data)(void * data))3403 _edje_box_layout_find(const char *name, Evas_Object_Box_Layout *cb, void **data, void(**free_data) (void *data))
3404 {
3405 const Edje_Box_Layout *l;
3406
3407 if (!name) return EINA_FALSE;
3408
3409 *cb = _edje_box_layout_builtin_find(name);
3410 if (*cb)
3411 {
3412 *free_data = NULL;
3413 *data = NULL;
3414 return EINA_TRUE;
3415 }
3416
3417 l = _edje_box_layout_part_external_find(name);
3418 if (!l) return EINA_FALSE;
3419
3420 *cb = l->func;
3421 *free_data = l->layout_data_free;
3422 if (l->layout_data_get)
3423 *data = l->layout_data_get(l->data);
3424 else
3425 *data = NULL;
3426
3427 return EINA_TRUE;
3428 }
3429
3430 static void
_edje_box_layout_part_external_free(Eina_Rbtree * node,void * data EINA_UNUSED)3431 _edje_box_layout_part_external_free(Eina_Rbtree *node, void *data EINA_UNUSED)
3432 {
3433 Edje_Box_Layout *l = (Edje_Box_Layout *)node;
3434
3435 if (l->data && l->free_data)
3436 l->free_data(l->data);
3437 free(l);
3438 }
3439
3440 static Edje_Box_Layout *
_edje_box_layout_part_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)3441 _edje_box_layout_part_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)
3442 {
3443 Edje_Box_Layout *l;
3444 size_t name_len;
3445
3446 name_len = strlen(name) + 1;
3447 l = malloc(sizeof(Edje_Box_Layout) + name_len);
3448 if (!l) return NULL;
3449
3450 l->func = func;
3451 l->layout_data_get = layout_data_get;
3452 l->layout_data_free = layout_data_free;
3453 l->free_data = free_data;
3454 l->data = data;
3455
3456 memcpy(l->name, name, name_len);
3457
3458 return l;
3459 }
3460
3461 EAPI void
edje_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)3462 edje_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)
3463 {
3464 Edje_Box_Layout *l;
3465
3466 if (!name) return;
3467
3468 if (_edje_box_layout_builtin_find(name))
3469 {
3470 ERR("Cannot register layout '%s': would override builtin!",
3471 name);
3472
3473 if (data && free_data) free_data(data);
3474 return;
3475 }
3476
3477 l = _edje_box_layout_part_external_find(name);
3478 if (!l)
3479 {
3480 if (!func)
3481 {
3482 if (data && free_data) free_data(data);
3483 return;
3484 }
3485
3486 l = _edje_box_layout_part_external_new
3487 (name, func, layout_data_get, layout_data_free, free_data, data);
3488 if (!l)
3489 return;
3490
3491 _edje_box_layout_registry = eina_rbtree_inline_insert
3492 (_edje_box_layout_registry, (Eina_Rbtree *)l,
3493 _edje_box_layout_part_external_node_cmp, NULL);
3494 }
3495 else
3496 {
3497 if (func)
3498 {
3499 if (l->data && l->free_data) l->free_data(l->data);
3500
3501 l->func = func;
3502 l->layout_data_get = layout_data_get;
3503 l->layout_data_free = layout_data_free;
3504 l->free_data = free_data;
3505 l->data = data;
3506 }
3507 else
3508 {
3509 if (data && free_data) free_data(data);
3510
3511 _edje_box_layout_registry = eina_rbtree_inline_remove
3512 (_edje_box_layout_registry, (Eina_Rbtree *)l,
3513 _edje_box_layout_part_external_node_cmp, NULL);
3514 _edje_box_layout_part_external_free((Eina_Rbtree *)l, NULL);
3515 }
3516 }
3517 }
3518
3519 static Edje_Real_Part *
_swallow_real_part_get(Evas_Object * obj_swallow)3520 _swallow_real_part_get(Evas_Object *obj_swallow)
3521 {
3522 Edje_Real_Part *rp;
3523
3524 if (!obj_swallow)
3525 return NULL;
3526
3527 rp = (Edje_Real_Part *)evas_object_data_get(obj_swallow, "\377 edje.swallowing_part");
3528 if (!rp)
3529 return NULL;
3530 if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
3531 {
3532 ERR("part %s is not a swallow type!", rp->part->name);
3533 return NULL;
3534 }
3535
3536 if ((rp->type != EDJE_RP_TYPE_SWALLOW) || (!rp->typedata.swallow))
3537 return NULL;
3538
3539 if (rp->typedata.swallow->swallowed_object == obj_swallow)
3540 return rp;
3541
3542 return NULL;
3543 }
3544
3545 EOLIAN Eina_Bool
_efl_canvas_layout_content_remove(Eo * obj EINA_UNUSED,Edje * ed,Evas_Object * obj_swallow)3546 _efl_canvas_layout_content_remove(Eo *obj EINA_UNUSED, Edje *ed, Evas_Object *obj_swallow)
3547 {
3548 Edje_Real_Part *rp;
3549 Edje_User_Defined *eud;
3550 Eina_Iterator *it;
3551 Eina_List *l, *ll;
3552
3553 rp = _swallow_real_part_get(obj_swallow);
3554 if (!rp) return EINA_FALSE;
3555
3556 it = eina_hash_iterator_data_new(ed->user_defined);
3557 EINA_ITERATOR_FOREACH(it, l)
3558 {
3559 EINA_LIST_FOREACH(l, ll, eud)
3560 if ((eud->type == EDJE_USER_SWALLOW) && (eud->u.swallow.child == obj_swallow))
3561 {
3562 _edje_user_definition_free(eud);
3563 eina_iterator_free(it);
3564 return EINA_TRUE;
3565 }
3566 }
3567 eina_iterator_free(it);
3568 _edje_real_part_swallow_clear(ed, rp);
3569 rp->typedata.swallow->swallowed_object = NULL;
3570 rp->typedata.swallow->swallow_params.min.w = 0;
3571 rp->typedata.swallow->swallow_params.min.h = 0;
3572 rp->typedata.swallow->swallow_params.max.w = 0;
3573 rp->typedata.swallow->swallow_params.max.h = 0;
3574 ed->dirty = EINA_TRUE;
3575 ed->recalc_call = EINA_TRUE;
3576 #ifdef EDJE_CALC_CACHE
3577 rp->invalidate = EINA_TRUE;
3578 #endif
3579 /* this seems to be as unnecessary as the calc in part_swallow()
3580 * -zmike, 6 April 2015
3581 */
3582 //_edje_recalc_do(ed);
3583
3584 return EINA_TRUE;
3585 }
3586
3587 typedef struct _Content_Part_Iterator Content_Part_Iterator;
3588 struct _Content_Part_Iterator
3589 {
3590 Eina_Iterator iterator;
3591 Eo *object;
3592 Edje *ed;
3593 unsigned index;
3594 };
3595
3596 static Eina_Bool
_content_part_iterator_next(Content_Part_Iterator * it,void ** data)3597 _content_part_iterator_next(Content_Part_Iterator *it, void **data)
3598 {
3599 for (; it->index < it->ed->table_parts_size; it->index++)
3600 {
3601 Edje_Real_Part *rp = it->ed->table_parts[it->index];
3602 if (rp->part && rp->part->type == EDJE_PART_TYPE_SWALLOW)
3603 {
3604 if (data) *data = (void*) rp->typedata.swallow->swallowed_object;
3605 it->index++;
3606 return EINA_TRUE;
3607 }
3608 }
3609
3610 return EINA_FALSE;
3611 }
3612
3613 static Eo *
_content_part_iterator_get_container(Content_Part_Iterator * it)3614 _content_part_iterator_get_container(Content_Part_Iterator *it)
3615 {
3616 return it->object;
3617 }
3618
3619 static void
_content_part_iterator_free(Content_Part_Iterator * it)3620 _content_part_iterator_free(Content_Part_Iterator *it)
3621 {
3622 free(it);
3623 }
3624
3625 EOLIAN Eina_Iterator*
_efl_canvas_layout_efl_container_content_iterate(Eo * obj,Edje * ed)3626 _efl_canvas_layout_efl_container_content_iterate(Eo *obj, Edje *ed)
3627 {
3628 Content_Part_Iterator *it;
3629
3630 it = calloc(1, sizeof(*it));
3631 if (!it) return NULL;
3632
3633 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
3634
3635 it->iterator.version = EINA_ITERATOR_VERSION;
3636 it->iterator.next = FUNC_ITERATOR_NEXT(_content_part_iterator_next);
3637 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_content_part_iterator_get_container);
3638 it->iterator.free = FUNC_ITERATOR_FREE(_content_part_iterator_free);
3639 it->object = obj;
3640 it->ed = ed;
3641 it->index = 0;
3642
3643 return &it->iterator;
3644 }
3645
3646 EOLIAN int
_efl_canvas_layout_efl_container_content_count(Eo * obj EINA_UNUSED,Edje * pd)3647 _efl_canvas_layout_efl_container_content_count(Eo *obj EINA_UNUSED, Edje *pd)
3648 {
3649 Edje_Real_Part *rp;
3650 int result = 0;
3651
3652 for (int i = 0; i < pd->table_parts_size; ++i)
3653 {
3654 rp = pd->table_parts[i];
3655 if (rp->part && rp->part->type == EDJE_PART_TYPE_SWALLOW)
3656 result ++;
3657 }
3658
3659 return result;
3660 }
3661
3662
3663 Efl_Gfx_Entity *
_edje_efl_content_content_get(Edje * ed,const char * part)3664 _edje_efl_content_content_get(Edje *ed, const char *part)
3665 {
3666 Edje_Real_Part *rp;
3667
3668 if ((!ed) || (!part)) return NULL;
3669
3670 rp = _edje_real_part_recursive_get(&ed, part);
3671 if (!rp) return NULL;
3672
3673 if (rp->type != EDJE_RP_TYPE_SWALLOW)
3674 {
3675 ERR("Edje group '%s' part '%s' is not a swallow. Did "
3676 "you mean to call efl_part() instead?", ed->group, part);
3677 return NULL;
3678 }
3679
3680 if (!rp->typedata.swallow) return NULL;
3681 return rp->typedata.swallow->swallowed_object;
3682 }
3683
3684 EOLIAN Eo *
_efl_canvas_layout_efl_part_part_get(Eo * obj,Edje * ed,const char * part)3685 _efl_canvas_layout_efl_part_part_get(Eo *obj, Edje *ed, const char *part)
3686 {
3687 Edje_Real_Part *rp;
3688
3689 if ((!ed) || (!part)) return NULL;
3690
3691 rp = _edje_real_part_recursive_get(&ed, part);
3692 if (!rp)
3693 {
3694 // Note: This could be disabled if debug is not required.
3695 static const Edje_Real_Part _invalid_part = {};
3696 rp = (Edje_Real_Part *) &_invalid_part;
3697 return _edje_invalid_internal_proxy_get(obj, ed, rp, part);
3698 }
3699
3700 if (rp->part->type == EDJE_PART_TYPE_BOX)
3701 return _edje_box_internal_proxy_get(obj, ed, rp, rp->part->name);
3702 else if (rp->part->type == EDJE_PART_TYPE_TABLE)
3703 return _edje_table_internal_proxy_get(obj, ed, rp, rp->part->name);
3704 else if (rp->part->type == EDJE_PART_TYPE_SWALLOW)
3705 return _edje_swallow_internal_proxy_get(obj, ed, rp, rp->part->name);
3706 else if (rp->part->type == EDJE_PART_TYPE_EXTERNAL)
3707 return _edje_external_internal_proxy_get(obj, ed, rp, rp->part->name);
3708 else if (rp->part->type == EDJE_PART_TYPE_TEXT)
3709 return _edje_text_internal_proxy_get(obj, ed, rp, rp->part->name);
3710 else if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
3711 return _edje_text_internal_proxy_get(obj, ed, rp, rp->part->name);
3712 else
3713 return _edje_other_internal_proxy_get(obj, ed, rp, rp->part->name);
3714 }
3715
3716 EOLIAN Eina_Size2D
_efl_canvas_layout_efl_layout_group_group_size_min_get(const Eo * obj EINA_UNUSED,Edje * ed)3717 _efl_canvas_layout_efl_layout_group_group_size_min_get(const Eo *obj EINA_UNUSED, Edje *ed)
3718 {
3719 if ((!ed) || (!ed->collection))
3720 return EINA_SIZE2D(0, 0);
3721
3722 return ed->collection->prop.min;
3723 }
3724
3725 EOLIAN Eina_Size2D
_efl_canvas_layout_efl_layout_group_group_size_max_get(const Eo * obj EINA_UNUSED,Edje * ed)3726 _efl_canvas_layout_efl_layout_group_group_size_max_get(const Eo *obj EINA_UNUSED, Edje *ed)
3727 {
3728 Eina_Size2D sz;
3729
3730 if ((!ed) || (!ed->collection))
3731 return EINA_SIZE2D(0, 0);
3732
3733 /* Need to recalc before providing the object. */
3734 if (!ed->freeze) EDJE_RECALC_DO(ed);
3735
3736 sz = ed->collection->prop.max;
3737
3738 /* XXX TODO: use 0 as max, fix things that break. */
3739 if (sz.w == 0) sz.w = EDJE_INF_MAX_W;
3740 if (sz.h == 0) sz.h = EDJE_INF_MAX_H;
3741 return sz;
3742 }
3743
3744 EOLIAN Eina_Bool
_efl_canvas_layout_efl_layout_group_part_exist_get(const Eo * obj EINA_UNUSED,Edje * ed,const char * part)3745 _efl_canvas_layout_efl_layout_group_part_exist_get(const Eo *obj EINA_UNUSED, Edje *ed, const char *part)
3746 {
3747 Edje_Real_Part *rp;
3748
3749 if (!part) return EINA_FALSE;
3750 if (ed->delete_me) return EINA_FALSE;
3751 rp = _edje_real_part_recursive_get(&ed, part);
3752 if (!rp) return EINA_FALSE;
3753
3754 return EINA_TRUE;
3755 }
3756
3757 EOLIAN void
_efl_canvas_layout_efl_layout_calc_calc_force(Eo * obj EINA_UNUSED,Edje * ed)3758 _efl_canvas_layout_efl_layout_calc_calc_force(Eo *obj EINA_UNUSED, Edje *ed)
3759 {
3760 int pf, pf2;
3761
3762 if (!ed) return;
3763 ed->dirty = EINA_TRUE;
3764 #ifdef EDJE_CALC_CACHE
3765 ed->all_part_change = EINA_TRUE;
3766 #endif
3767
3768 pf2 = _edje_util_freeze_val;
3769 pf = ed->freeze;
3770
3771 _edje_util_freeze_val = 0;
3772 ed->freeze = 0;
3773
3774 _edje_recalc_do(ed);
3775
3776 ed->freeze = pf;
3777 _edje_util_freeze_val = pf2;
3778 }
3779
3780 EOLIAN Eina_Rect
_efl_canvas_layout_efl_layout_calc_calc_parts_extends(Eo * obj EINA_UNUSED,Edje * ed)3781 _efl_canvas_layout_efl_layout_calc_calc_parts_extends(Eo *obj EINA_UNUSED, Edje *ed)
3782 {
3783 Evas_Coord xx1 = INT_MAX, yy1 = INT_MAX;
3784 Evas_Coord xx2 = 0, yy2 = 0, w = 0, h = 0;
3785 unsigned short i;
3786
3787 ed->calc_only = EINA_TRUE;
3788
3789 /* Need to recalc before providing the object. */
3790 ed->dirty = EINA_TRUE;
3791 _edje_recalc_do(ed);
3792
3793 for (i = 0; i < ed->table_parts_size; i++)
3794 {
3795 Edje_Real_Part *rp;
3796 Evas_Coord rpx1, rpy1;
3797 Evas_Coord rpx2, rpy2;
3798
3799 rp = ed->table_parts[i];
3800
3801 rpx1 = rp->x;
3802 rpy1 = rp->y;
3803 rpx2 = rpx1 + rp->w;
3804 rpy2 = rpy1 + rp->h;
3805
3806 if (xx1 > rpx1) xx1 = rpx1;
3807 if (yy1 > rpy1) yy1 = rpy1;
3808 if (xx2 < rpx2) xx2 = rpx2;
3809 if (yy2 < rpy2) yy2 = rpy2;
3810 }
3811
3812 ed->calc_only = EINA_FALSE;
3813
3814 if ((xx2 - xx1) > 0) w = xx2 - xx1;
3815 if ((yy2 - yy1) > 0) h = yy2 - yy1;
3816
3817 return (Eina_Rect) { (Eina_Rectangle) { xx1, yy1, w, h } };
3818 }
3819
3820 EOLIAN Eina_Size2D
_efl_canvas_layout_efl_layout_calc_calc_size_min(Eo * obj EINA_UNUSED,Edje * ed,Eina_Size2D restricted)3821 _efl_canvas_layout_efl_layout_calc_calc_size_min(Eo *obj EINA_UNUSED, Edje *ed, Eina_Size2D restricted)
3822 {
3823 const int CALC_COUNT_LIMIT = 255;
3824
3825 Evas_Coord orig_w, orig_h; //original edje size
3826 int max_over_w, max_over_h; //maximum over-calculated size.
3827 int calc_count = 0;
3828 Eina_Bool repeat_w, repeat_h;
3829 Eina_Bool reset_max = EINA_TRUE;
3830 Edje_Real_Part *pep = NULL;
3831 /* Only for legacy calculation logic */
3832 Evas_Coord ins_l, ins_r;
3833 Eina_Bool has_fixed_tb;
3834 Eina_Bool legacy_calc;
3835 Eina_Size2D ret;
3836
3837 if ((!ed) || (!ed->collection))
3838 return restricted;
3839
3840 /*
3841 * It decides a calculation logic according to efl_version of Edje file.
3842 * There was wrong/special consideration for Textblock parts.
3843 * Becasue of that, Textblock parts can have minimum size according to its text contents
3844 * even if there is [text.min: 0 0]. It made people confused.
3845 *
3846 * To keep backward compatibility, legacy_calc will be used for old version of EDJ files.
3847 * With enabling legacy_calc, You can't see proper min/max result accroding to documents.
3848 */
3849 if (!ed->file || ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19)))
3850 legacy_calc = EINA_FALSE;
3851 else
3852 legacy_calc = EINA_TRUE;
3853
3854 //Simulate object minimum size.
3855 ed->calc_only = EINA_TRUE;
3856
3857 orig_w = ed->w;
3858 orig_h = ed->h;
3859
3860 again:
3861 //restrict minimum size to
3862 ed->w = restricted.w;
3863 ed->h = restricted.h;
3864
3865 max_over_w = 0;
3866 max_over_h = 0;
3867
3868 do
3869 {
3870 unsigned short i;
3871
3872 calc_count++;
3873
3874 repeat_w = EINA_FALSE;
3875 repeat_h = EINA_FALSE;
3876 ed->dirty = EINA_TRUE;
3877 #ifdef EDJE_CALC_CACHE
3878 ed->all_part_change = EINA_TRUE;
3879 #endif
3880 _edje_recalc_do(ed);
3881
3882 if (reset_max)
3883 {
3884 max_over_w = 0;
3885 max_over_h = 0;
3886 }
3887
3888 pep = NULL;
3889 /* Only for legacy calculation logic */
3890 has_fixed_tb = EINA_TRUE;
3891
3892 //for parts
3893 for (i = 0; i < ed->table_parts_size; i++)
3894 {
3895 Edje_Real_Part *ep = ed->table_parts[i];
3896
3897 if (!ep->chosen_description) continue;
3898
3899 //diff, how much it's over-sized.
3900 int over_w = (ep->w - ep->req.w);
3901 int over_h = (ep->h - ep->req.h);
3902
3903 /* Only for legacy calculation logic */
3904 Eina_Bool skip_h = EINA_FALSE;
3905
3906 //width
3907 if (!ep->chosen_description->fixed.w)
3908 {
3909 if ((legacy_calc) && (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK))
3910 {
3911 //We care textblock width size specially.
3912 Evas_Coord tb_mw;
3913 evas_object_textblock_size_formatted_get(ep->object,
3914 &tb_mw, NULL);
3915 evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r, NULL, NULL);
3916 tb_mw = ins_l + tb_mw + ins_r;
3917 tb_mw -= ep->req.w;
3918 if (tb_mw > over_w) over_w = tb_mw;
3919 has_fixed_tb = EINA_FALSE;
3920 }
3921
3922 if (over_w > max_over_w)
3923 {
3924 max_over_w = over_w;
3925 repeat_w = EINA_TRUE;
3926 pep = ep;
3927
3928 /* Only for legacy calculation logic */
3929 skip_h = EINA_TRUE;
3930 }
3931 }
3932 //height
3933 if (!ep->chosen_description->fixed.h)
3934 {
3935 if (legacy_calc)
3936 {
3937 if ((ep->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3938 ((Edje_Part_Description_Text *)ep->chosen_description)->text.min_x ||
3939 !skip_h)
3940 {
3941 if (over_h > max_over_h)
3942 {
3943 max_over_h = over_h;
3944 repeat_h = EINA_TRUE;
3945 pep = ep;
3946 }
3947 }
3948
3949 if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
3950 has_fixed_tb = EINA_FALSE;
3951 }
3952 else if (over_h > max_over_h)
3953 {
3954 max_over_h = over_h;
3955 repeat_h = EINA_TRUE;
3956 pep = ep;
3957 }
3958 }
3959 }
3960 if (repeat_w)
3961 {
3962 ed->w += max_over_w;
3963
3964 //exceptional handling.
3965 if (ed->w < restricted.w) ed->w = restricted.w;
3966 }
3967 if (repeat_h)
3968 {
3969 ed->h += max_over_h;
3970
3971 //exceptional handling.
3972 if (ed->h < restricted.h) ed->h = restricted.h;
3973 }
3974
3975 if (reset_max && (calc_count > CALC_COUNT_LIMIT))
3976 {
3977 if (legacy_calc)
3978 {
3979 /* Only print it if we have a non-fixed textblock.
3980 * We should possibly avoid all of this if in this case, but in
3981 * the meanwhile, just doing this. */
3982 if (!has_fixed_tb)
3983 {
3984 if (pep)
3985 ERR("file %s, group %s has a non-fixed part '%s'. Adding 'fixed: 1 1;' to source EDC may help. Continuing discarding faulty part.",
3986 ed->path, ed->group, pep->part->name);
3987 else
3988 ERR("file %s, group %s runs infinite minimum calculation loops.Continuing discarding faulty parts.",
3989 ed->path, ed->group);
3990 }
3991 }
3992 else
3993 {
3994 /* We should possibly avoid all of this if in this case, but in
3995 * the meanwhile, just doing this. */
3996 if (pep)
3997 ERR("file %s, group %s has a non-fixed part '%s'. Adding 'fixed: 1 1;' to source EDC may help. Continuing discarding faulty part.",
3998 ed->path, ed->group, pep->part->name);
3999 else
4000 ERR("file %s, group %s runs infinite minimum calculation loops.Continuing discarding faulty parts.",
4001 ed->path, ed->group);
4002 }
4003
4004 reset_max = EINA_FALSE;
4005 goto again;
4006 }
4007 }
4008 while (repeat_w || repeat_h);
4009
4010 ed->min.w = ed->w;
4011 ed->min.h = ed->h;
4012 ret = EINA_SIZE2D(ed->min.w, ed->min.h);
4013
4014 ed->w = orig_w;
4015 ed->h = orig_h;
4016
4017 ed->dirty = EINA_TRUE;
4018 #ifdef EDJE_CALC_CACHE
4019 ed->all_part_change = EINA_TRUE;
4020 #endif
4021 _edje_recalc(ed);
4022 ed->calc_only = EINA_FALSE;
4023
4024 return ret;
4025 }
4026
4027 /* FIXME: Correctly return other states */
4028 const char *
_edje_object_part_state_get(Edje * ed,const char * part,double * val_ret)4029 _edje_object_part_state_get(Edje *ed, const char *part, double *val_ret)
4030 {
4031 const char *ret;
4032
4033 Edje_Real_Part *rp;
4034 ret = "";
4035
4036 if ((!ed) || (!part))
4037 {
4038 if (val_ret) *val_ret = 0;
4039 return ret;
4040 }
4041
4042 /* Need to recalc before providing the object. */
4043 _edje_recalc_do(ed);
4044
4045 rp = _edje_real_part_recursive_get(&ed, part);
4046 if (!rp)
4047 {
4048 if (val_ret) *val_ret = 0;
4049 INF("part not found");
4050 return ret;
4051 }
4052 if (rp->chosen_description)
4053 {
4054 if (val_ret) *val_ret = rp->chosen_description->state.value;
4055 if (rp->chosen_description->state.name)
4056 ret = rp->chosen_description->state.name;
4057 else
4058 ret = "default";
4059 return ret;
4060 }
4061 else
4062 {
4063 if (rp->param1.description)
4064 {
4065 if (val_ret) *val_ret = rp->param1.description->state.value;
4066 if (rp->param1.description->state.name)
4067 ret = rp->param1.description->state.name;
4068 else
4069 ret = "default";
4070 return ret;
4071 }
4072 }
4073 if (val_ret) *val_ret = 0;
4074
4075 return ret;
4076 }
4077
4078 Edje_Drag_Dir
_edje_object_part_drag_dir_get(Edje * ed,const char * part)4079 _edje_object_part_drag_dir_get(Edje *ed, const char *part)
4080 {
4081 Edje_Drag_Dir ret;
4082 Edje_Real_Part *rp;
4083 ret = EDJE_DRAG_DIR_NONE;
4084
4085 if ((!ed) || (!part)) return ret;
4086
4087 /* Need to recalc before providing the object. */
4088 _edje_recalc_do(ed);
4089
4090 rp = _edje_real_part_recursive_get(&ed, part);
4091 if (!rp) return ret;
4092 if ((rp->part->dragable.x) && (rp->part->dragable.y)) ret = EDJE_DRAG_DIR_XY;
4093 else if (rp->part->dragable.x)
4094 ret = EDJE_DRAG_DIR_X;
4095 else if (rp->part->dragable.y)
4096 ret = EDJE_DRAG_DIR_Y;
4097
4098 return ret;
4099 }
4100
4101 Eina_Bool
_edje_object_part_drag_value_set(Edje * ed,const char * part,double dx,double dy)4102 _edje_object_part_drag_value_set(Edje *ed, const char *part, double dx, double dy)
4103 {
4104 Edje_Real_Part *rp = NULL;
4105 Edje_User_Defined *eud;
4106 Eina_List *l, *ll;
4107
4108 if ((!ed) || (!part)) return EINA_FALSE;
4109 if (ed->file)
4110 {
4111 rp = _edje_real_part_recursive_get(&ed, part);
4112 if (!rp) return EINA_FALSE;
4113 if (!rp->drag) return EINA_FALSE;
4114 }
4115
4116 l = eina_hash_find(ed->user_defined, part);
4117 EINA_LIST_FOREACH(l, ll, eud)
4118 if (eud->type == EDJE_USER_DRAG_VALUE)
4119 {
4120 eud->u.drag_position.x = dx;
4121 eud->u.drag_position.y = dy;
4122 break;
4123 }
4124 if (!eud)
4125 {
4126 eud = _edje_user_definition_new(EDJE_USER_DRAG_VALUE, part, ed);
4127 if (eud)
4128 {
4129 eud->u.drag_position.x = dx;
4130 eud->u.drag_position.y = dy;
4131 }
4132 }
4133 if (!ed->file) return EINA_TRUE;
4134
4135 if (rp->part->dragable.confine_id != -1)
4136 {
4137 dx = CLAMP(dx, 0.0, 1.0);
4138 dy = CLAMP(dy, 0.0, 1.0);
4139 }
4140 if (rp->part->dragable.x < 0) dx = 1.0 - dx;
4141 if (rp->part->dragable.y < 0) dy = 1.0 - dy;
4142 if (EQ(rp->drag->val.x, FROM_DOUBLE(dx)) && EQ(rp->drag->val.y, FROM_DOUBLE(dy)))
4143 {
4144 return EINA_TRUE;
4145 }
4146 rp->drag->val.x = FROM_DOUBLE(dx);
4147 rp->drag->val.y = FROM_DOUBLE(dy);
4148 #ifdef EDJE_CALC_CACHE
4149 rp->invalidate = EINA_TRUE;
4150 #endif
4151 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
4152 _edje_emit(ed, "drag,set", rp->part->name);
4153
4154 return EINA_TRUE;
4155 }
4156
4157 /* FIXME: Should this be x and y instead of dx/dy? */
4158 Eina_Bool
_edje_object_part_drag_value_get(Edje * ed,const char * part,double * dx,double * dy)4159 _edje_object_part_drag_value_get(Edje *ed, const char *part, double *dx, double *dy)
4160 {
4161 Edje_Real_Part *rp;
4162 double ddx, ddy;
4163
4164 if ((!ed) || (!part))
4165 {
4166 if (dx) *dx = 0;
4167 if (dy) *dy = 0;
4168 return EINA_FALSE;
4169 }
4170
4171 /* Need to recalc before providing the object. */
4172 _edje_recalc_do(ed);
4173
4174 rp = _edje_real_part_recursive_get(&ed, part);
4175 if (!rp || !rp->drag)
4176 {
4177 if (dx) *dx = 0;
4178 if (dy) *dy = 0;
4179 return EINA_FALSE;
4180 }
4181 ddx = TO_DOUBLE(rp->drag->val.x);
4182 ddy = TO_DOUBLE(rp->drag->val.y);
4183 if (rp->part->dragable.x < 0) ddx = 1.0 - ddx;
4184 if (rp->part->dragable.y < 0) ddy = 1.0 - ddy;
4185 if (dx) *dx = ddx;
4186 if (dy) *dy = ddy;
4187
4188 return EINA_TRUE;
4189 }
4190
4191 Eina_Bool
_edje_object_part_drag_size_set(Edje * ed,const char * part,double dw,double dh)4192 _edje_object_part_drag_size_set(Edje *ed, const char *part, double dw, double dh)
4193 {
4194 Edje_Real_Part *rp = NULL;
4195 Edje_User_Defined *eud;
4196 Eina_List *l, *ll;
4197
4198 if ((!ed) || (!part)) return EINA_FALSE;
4199 rp = _edje_real_part_recursive_get(&ed, part);
4200 if (ed->file)
4201 {
4202 if (!rp) return EINA_FALSE;
4203 if (!rp->drag) return EINA_FALSE;
4204 }
4205
4206 l = eina_hash_find(ed->user_defined, part);
4207 EINA_LIST_FOREACH(l, ll, eud)
4208 if (eud->type == EDJE_USER_DRAG_SIZE)
4209 {
4210 eud->u.drag_size.w = dw;
4211 eud->u.drag_size.h = dh;
4212 break;
4213 }
4214 if (!eud)
4215 {
4216 eud = _edje_user_definition_new(EDJE_USER_DRAG_SIZE, part, ed);
4217 if (eud)
4218 {
4219 eud->u.drag_size.w = dw;
4220 eud->u.drag_size.h = dh;
4221 }
4222 }
4223 if (!ed->file) return EINA_TRUE;
4224
4225 if (dw < 0.0) dw = 0.0;
4226 else if (dw > 1.0)
4227 dw = 1.0;
4228 if (dh < 0.0) dh = 0.0;
4229 else if (dh > 1.0)
4230 dh = 1.0;
4231 if (EQ(rp->drag->size.x, FROM_DOUBLE(dw)) && EQ(rp->drag->size.y, FROM_DOUBLE(dh)))
4232 {
4233 return EINA_TRUE;
4234 }
4235 rp->drag->size.x = FROM_DOUBLE(dw);
4236 rp->drag->size.y = FROM_DOUBLE(dh);
4237 ed->dirty = EINA_TRUE;
4238 ed->recalc_call = EINA_TRUE;
4239 #ifdef EDJE_CALC_CACHE
4240 rp->invalidate = EINA_TRUE;
4241 #endif
4242 _edje_recalc(ed);
4243
4244 return EINA_TRUE;
4245 }
4246
4247 Eina_Bool
_edje_object_part_drag_size_get(Edje * ed,const char * part,double * dw,double * dh)4248 _edje_object_part_drag_size_get(Edje *ed, const char *part, double *dw, double *dh)
4249 {
4250 Edje_Real_Part *rp;
4251
4252 if ((!ed) || (!part))
4253 {
4254 if (dw) *dw = 0;
4255 if (dh) *dh = 0;
4256 return EINA_FALSE;
4257 }
4258
4259 /* Need to recalc before providing the object. */
4260 _edje_recalc_do(ed);
4261
4262 rp = _edje_real_part_recursive_get(&ed, part);
4263 if (!rp || !rp->drag)
4264 {
4265 if (dw) *dw = 0;
4266 if (dh) *dh = 0;
4267 return EINA_FALSE;
4268 }
4269 if (dw) *dw = TO_DOUBLE(rp->drag->size.x);
4270 if (dh) *dh = TO_DOUBLE(rp->drag->size.y);
4271
4272 return EINA_TRUE;
4273 }
4274
4275 Eina_Bool
_edje_object_part_drag_step_set(Edje * ed,const char * part,double dx,double dy)4276 _edje_object_part_drag_step_set(Edje *ed, const char *part, double dx, double dy)
4277 {
4278 Edje_Real_Part *rp = NULL;
4279 Edje_User_Defined *eud;
4280 Eina_List *l, *ll;
4281
4282 if ((!ed) || (!part)) return EINA_FALSE;
4283 rp = _edje_real_part_recursive_get(&ed, part);
4284 if (ed->file)
4285 {
4286 if (!rp) return EINA_FALSE;
4287 if (!rp->drag) return EINA_FALSE;
4288 }
4289
4290 l = eina_hash_find(ed->user_defined, part);
4291 EINA_LIST_FOREACH(l, ll, eud)
4292 if (eud->type == EDJE_USER_DRAG_STEP)
4293 {
4294 eud->u.drag_position.x = dx;
4295 eud->u.drag_position.y = dy;
4296 break;
4297 }
4298 if (!eud)
4299 {
4300 eud = _edje_user_definition_new(EDJE_USER_DRAG_STEP, part, ed);
4301 if (eud)
4302 {
4303 eud->u.drag_position.x = dx;
4304 eud->u.drag_position.y = dy;
4305 }
4306 }
4307 if (!ed->file) return EINA_TRUE;
4308
4309 if (dx < 0.0) dx = 0.0;
4310 else if (dx > 1.0)
4311 dx = 1.0;
4312 if (dy < 0.0) dy = 0.0;
4313 else if (dy > 1.0)
4314 dy = 1.0;
4315 rp->drag->step.x = FROM_DOUBLE(dx);
4316 rp->drag->step.y = FROM_DOUBLE(dy);
4317 #ifdef EDJE_CALC_CACHE
4318 rp->invalidate = EINA_TRUE;
4319 #endif
4320
4321 return EINA_TRUE;
4322 }
4323
4324 Eina_Bool
_edje_object_part_drag_step_get(Edje * ed,const char * part,double * dx,double * dy)4325 _edje_object_part_drag_step_get(Edje *ed, const char *part, double *dx, double *dy)
4326 {
4327 Edje_Real_Part *rp;
4328
4329 if ((!ed) || (!part))
4330 {
4331 if (dx) *dx = 0;
4332 if (dy) *dy = 0;
4333 return EINA_FALSE;
4334 }
4335
4336 /* Need to recalc before providing the object. */
4337 _edje_recalc_do(ed);
4338
4339 rp = _edje_real_part_recursive_get(&ed, part);
4340 if (!rp || !rp->drag)
4341 {
4342 if (dx) *dx = 0;
4343 if (dy) *dy = 0;
4344 return EINA_FALSE;
4345 }
4346 if (dx) *dx = TO_DOUBLE(rp->drag->step.x);
4347 if (dy) *dy = TO_DOUBLE(rp->drag->step.y);
4348
4349 return EINA_TRUE;
4350 }
4351
4352 Eina_Bool
_edje_object_part_drag_page_set(Edje * ed,const char * part,double dx,double dy)4353 _edje_object_part_drag_page_set(Edje *ed, const char *part, double dx, double dy)
4354 {
4355 Edje_Real_Part *rp = NULL;
4356 Edje_User_Defined *eud;
4357 Eina_List *l, *ll;
4358
4359 if ((!ed) || (!part)) return EINA_FALSE;
4360 if (ed->file)
4361 {
4362 rp = _edje_real_part_recursive_get(&ed, part);
4363 if (!rp) return EINA_FALSE;
4364 if (!rp->drag) return EINA_FALSE;
4365 }
4366
4367 l = eina_hash_find(ed->user_defined, part);
4368 EINA_LIST_FOREACH(l, ll, eud)
4369 if (eud->type == EDJE_USER_DRAG_PAGE)
4370 {
4371 eud->u.drag_position.x = dx;
4372 eud->u.drag_position.y = dy;
4373 break;
4374 }
4375 if (!eud)
4376 {
4377 eud = _edje_user_definition_new(EDJE_USER_DRAG_PAGE, part, ed);
4378 if (eud)
4379 {
4380 eud->u.drag_position.x = dx;
4381 eud->u.drag_position.y = dy;
4382 }
4383 }
4384 if (!ed->file) return EINA_TRUE;
4385
4386 if (dx < 0.0) dx = 0.0;
4387 else if (dx > 1.0)
4388 dx = 1.0;
4389 if (dy < 0.0) dy = 0.0;
4390 else if (dy > 1.0)
4391 dy = 1.0;
4392 rp->drag->page.x = FROM_DOUBLE(dx);
4393 rp->drag->page.y = FROM_DOUBLE(dy);
4394 #ifdef EDJE_CALC_CACHE
4395 rp->invalidate = EINA_TRUE;
4396 #endif
4397
4398 return EINA_TRUE;
4399 }
4400
4401 Eina_Bool
_edje_object_part_drag_page_get(Edje * ed,const char * part,double * dx,double * dy)4402 _edje_object_part_drag_page_get(Edje *ed, const char *part, double *dx, double *dy)
4403 {
4404 Edje_Real_Part *rp;
4405
4406 if ((!ed) || (!part))
4407 {
4408 if (dx) *dx = 0;
4409 if (dy) *dy = 0;
4410 return EINA_FALSE;
4411 }
4412
4413 /* Need to recalc before providing the object. */
4414 _edje_recalc_do(ed);
4415
4416 rp = _edje_real_part_recursive_get(&ed, part);
4417 if (!rp || !rp->drag)
4418 {
4419 if (dx) *dx = 0;
4420 if (dy) *dy = 0;
4421 return EINA_FALSE;
4422 }
4423 if (dx) *dx = TO_DOUBLE(rp->drag->page.x);
4424 if (dy) *dy = TO_DOUBLE(rp->drag->page.y);
4425
4426 return EINA_TRUE;
4427 }
4428
4429 Eina_Bool
_edje_object_part_drag_step(Edje * ed,const char * part,double dx,double dy)4430 _edje_object_part_drag_step(Edje *ed, const char *part, double dx, double dy)
4431 {
4432 Edje_Real_Part *rp = NULL;
4433 FLOAT_T px, py;
4434 Edje_User_Defined *eud;
4435 Eina_List *l, *ll;
4436
4437 if ((!ed) || (!part)) return EINA_FALSE;
4438 if (ed->file)
4439 {
4440 rp = _edje_real_part_recursive_get(&ed, part);
4441 if (!rp) return EINA_FALSE;
4442 if (!rp->drag) return EINA_FALSE;
4443 }
4444
4445 l = eina_hash_find(ed->user_defined, part);
4446 EINA_LIST_FOREACH(l, ll, eud)
4447 if (eud->type == EDJE_USER_DRAG_STEP)
4448 {
4449 eud->u.drag_position.x = dx;
4450 eud->u.drag_position.y = dy;
4451 break;
4452 }
4453 if (!eud)
4454 {
4455 eud = _edje_user_definition_new(EDJE_USER_DRAG_STEP, part, ed);
4456 if (eud)
4457 {
4458 eud->u.drag_position.x = dx;
4459 eud->u.drag_position.y = dy;
4460 }
4461 }
4462 if (!ed->file) return EINA_TRUE;
4463
4464 px = rp->drag->val.x;
4465 py = rp->drag->val.y;
4466 rp->drag->val.x = ADD(px, MUL(FROM_DOUBLE(dx),
4467 MUL(rp->drag->step.x, rp->part->dragable.x)));
4468 rp->drag->val.y = ADD(py, MUL(FROM_DOUBLE(dy),
4469 MUL(rp->drag->step.y, rp->part->dragable.y)));
4470 rp->drag->val.x = CLAMP(rp->drag->val.x, ZERO, FROM_DOUBLE(1.0));
4471 rp->drag->val.y = CLAMP(rp->drag->val.y, ZERO, FROM_DOUBLE(1.0));
4472 if (EQ(px, rp->drag->val.x) && EQ(py, rp->drag->val.y))
4473 {
4474 return EINA_TRUE;
4475 }
4476 #ifdef EDJE_CALC_CACHE
4477 rp->invalidate = EINA_TRUE;
4478 #endif
4479 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
4480 _edje_emit(ed, "drag,step", rp->part->name);
4481
4482 return EINA_TRUE;
4483 }
4484
4485 Eina_Bool
_edje_object_part_drag_page(Edje * ed,const char * part,double dx,double dy)4486 _edje_object_part_drag_page(Edje *ed, const char *part, double dx, double dy)
4487 {
4488 Edje_Real_Part *rp = NULL;
4489 FLOAT_T px, py;
4490 Edje_User_Defined *eud;
4491 Eina_List *l, *ll;
4492
4493 if ((!ed) || (!part)) return EINA_FALSE;
4494 if (ed->file)
4495 {
4496 rp = _edje_real_part_recursive_get(&ed, part);
4497 if (!rp) return EINA_FALSE;
4498 if (!rp->drag) return EINA_FALSE;
4499 }
4500
4501 l = eina_hash_find(ed->user_defined, part);
4502 EINA_LIST_FOREACH(l, ll, eud)
4503 if (eud->type == EDJE_USER_DRAG_PAGE)
4504 {
4505 eud->u.drag_position.x = dx;
4506 eud->u.drag_position.y = dy;
4507 break;
4508 }
4509 if (!eud)
4510 {
4511 eud = _edje_user_definition_new(EDJE_USER_DRAG_PAGE, part, ed);
4512 if (eud)
4513 {
4514 eud->u.drag_position.x = dx;
4515 eud->u.drag_position.y = dy;
4516 }
4517 }
4518 if (!ed->file) return EINA_TRUE;
4519
4520 px = rp->drag->val.x;
4521 py = rp->drag->val.y;
4522 rp->drag->val.x = ADD(px, MUL(FROM_DOUBLE(dx), MUL(rp->drag->page.x, rp->part->dragable.x)));
4523 rp->drag->val.y = ADD(py, MUL(FROM_DOUBLE(dy), MUL(rp->drag->page.y, rp->part->dragable.y)));
4524 rp->drag->val.x = CLAMP(rp->drag->val.x, ZERO, FROM_DOUBLE(1.0));
4525 rp->drag->val.y = CLAMP(rp->drag->val.y, ZERO, FROM_DOUBLE(1.0));
4526 if (EQ(px, rp->drag->val.x) && EQ(py, rp->drag->val.y))
4527 {
4528 return EINA_TRUE;
4529 }
4530 #ifdef EDJE_CALC_CACHE
4531 rp->invalidate = EINA_TRUE;
4532 #endif
4533 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
4534 _edje_emit(ed, "drag,page", rp->part->name);
4535
4536 return EINA_TRUE;
4537 }
4538
4539 void
_edje_box_init(void)4540 _edje_box_init(void)
4541 {
4542 }
4543
4544 void
_edje_box_shutdown(void)4545 _edje_box_shutdown(void)
4546 {
4547 if (!_edje_box_layout_registry)
4548 return;
4549
4550 eina_rbtree_delete
4551 (_edje_box_layout_registry, _edje_box_layout_part_external_free, NULL);
4552 _edje_box_layout_registry = NULL;
4553 }
4554
4555 Eina_Bool
_edje_part_box_append(Edje * ed,const char * part,Evas_Object * child)4556 _edje_part_box_append(Edje *ed, const char *part, Evas_Object *child)
4557 {
4558 Eina_Bool ret;
4559 Edje_Real_Part *rp = NULL;
4560 ret = EINA_FALSE;
4561
4562 if ((!ed) || (!part) || (!child)) return ret;
4563
4564 if (ed->file)
4565 {
4566 rp = _edje_real_part_recursive_get(&ed, part);
4567 if (!rp) return ret;
4568 if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
4569 }
4570
4571 if ((!ed->file) || _edje_real_part_box_append(ed, rp, child))
4572 {
4573 Edje_User_Defined *eud;
4574
4575 eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
4576 if (!eud) return ret;
4577 eud->u.box.child = child;
4578 eud->u.box.index = -1;
4579
4580 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
4581 ret = EINA_TRUE;
4582 }
4583
4584 return ret;
4585 }
4586
4587 Eina_Bool
_edje_part_box_prepend(Edje * ed,const char * part,Evas_Object * child)4588 _edje_part_box_prepend(Edje *ed, const char *part, Evas_Object *child)
4589 {
4590 Eina_Bool ret;
4591 Edje_Real_Part *rp = NULL;
4592 ret = EINA_FALSE;
4593
4594 if ((!ed) || (!part)) return ret;
4595
4596 if (ed->file)
4597 {
4598 rp = _edje_real_part_recursive_get(&ed, part);
4599 if (!rp) return ret;
4600 if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
4601 }
4602
4603 if ((!ed->file) || _edje_real_part_box_prepend(ed, rp, child))
4604 {
4605 Edje_User_Defined *eud;
4606
4607 eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
4608 if (!eud) return ret;
4609 eud->u.box.child = child;
4610
4611 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
4612 ret = EINA_TRUE;
4613 }
4614
4615 return ret;
4616 }
4617
4618 Eina_Bool
_edje_part_box_insert_before(Edje * ed,const char * part,Evas_Object * child,const Evas_Object * reference)4619 _edje_part_box_insert_before(Edje *ed, const char *part, Evas_Object *child, const Evas_Object *reference)
4620 {
4621 Eina_Bool ret;
4622 Edje_Real_Part *rp = NULL;
4623 ret = EINA_FALSE;
4624
4625 if ((!ed) || (!part)) return ret;
4626
4627 if (ed->file)
4628 {
4629 rp = _edje_real_part_recursive_get(&ed, part);
4630 if (!rp) return ret;
4631 if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
4632 }
4633
4634 if ((!ed->file) || _edje_real_part_box_insert_before(ed, rp, child, reference))
4635 {
4636 Edje_User_Defined *eud;
4637
4638 eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
4639 if (!eud) return ret;
4640 eud->u.box.child = child;
4641
4642 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
4643 ret = EINA_TRUE;
4644 }
4645
4646 return ret;
4647 }
4648
4649 Eina_Bool
_edje_part_box_insert_after(Edje * ed,const char * part,Evas_Object * child,const Evas_Object * reference)4650 _edje_part_box_insert_after(Edje *ed, const char *part, Evas_Object *child, const Evas_Object *reference)
4651 {
4652 Eina_Bool ret;
4653 Edje_Real_Part *rp = NULL;
4654 ret = EINA_FALSE;
4655
4656 if ((!ed) || (!part)) return ret;
4657
4658 if (ed->file)
4659 {
4660 rp = _edje_real_part_recursive_get(&ed, part);
4661 if (!rp) return ret;
4662 if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
4663 }
4664
4665 if ((!ed->file) || _edje_real_part_box_insert_after(ed, rp, child, reference))
4666 {
4667 Edje_User_Defined *eud;
4668
4669 eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
4670 if (!eud) return ret;
4671 eud->u.box.child = child;
4672
4673 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
4674 ret = EINA_TRUE;
4675 }
4676
4677 return ret;
4678 }
4679
4680 Eina_Bool
_edje_part_box_insert_at(Edje * ed,const char * part,Evas_Object * child,unsigned int pos)4681 _edje_part_box_insert_at(Edje *ed, const char *part, Evas_Object *child, unsigned int pos)
4682 {
4683 Eina_Bool ret;
4684 Edje_Real_Part *rp = NULL;
4685 ret = EINA_FALSE;
4686
4687 if ((!ed) || (!part)) return ret;
4688
4689 if (ed->file)
4690 {
4691 rp = _edje_real_part_recursive_get(&ed, part);
4692 if (!rp) return ret;
4693 if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
4694 }
4695
4696 if ((!ed->file) || _edje_real_part_box_insert_at(ed, rp, child, pos))
4697 {
4698 Edje_User_Defined *eud;
4699
4700 eud = _edje_user_definition_new(EDJE_USER_BOX_PACK, part, ed);
4701 if (!eud) return ret;
4702 eud->u.box.child = child;
4703
4704 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
4705 ret = EINA_TRUE;
4706 }
4707
4708 return ret;
4709 }
4710
4711 static void
_edje_part_box_remove_user_definition(Edje * ed,Eina_Stringshare * part,Evas_Object * child)4712 _edje_part_box_remove_user_definition(Edje *ed, Eina_Stringshare *part, Evas_Object *child)
4713 {
4714 Edje_User_Defined *eud;
4715 Eina_List *l, *ll;
4716
4717 l = eina_hash_find(ed->user_defined, part);
4718 EINA_LIST_FOREACH(l, ll, eud)
4719 if (eud->type == EDJE_USER_BOX_PACK && eud->u.box.child == child)
4720 {
4721 _edje_user_definition_free(eud);
4722 return;
4723 }
4724 }
4725
4726 Evas_Object *
_edje_part_box_remove(Edje * ed,const char * part,Evas_Object * child)4727 _edje_part_box_remove(Edje *ed, const char *part, Evas_Object *child)
4728 {
4729 Edje_Real_Part *rp;
4730 Evas_Object *r;
4731
4732 if ((!ed) || (!part)) return NULL;
4733
4734 rp = _edje_real_part_recursive_get(&ed, part);
4735 if (!rp) return NULL;
4736 if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
4737
4738 r = _edje_real_part_box_remove(ed, rp, child);
4739
4740 if (r) _edje_part_box_remove_user_definition(ed, part, r);
4741 return r;
4742 }
4743
4744 Evas_Object *
_edje_part_box_remove_at(Edje * ed,const char * part,unsigned int pos)4745 _edje_part_box_remove_at(Edje *ed, const char *part, unsigned int pos)
4746 {
4747 Edje_Real_Part *rp;
4748 Evas_Object *r;
4749
4750 if ((!ed) || (!part)) return NULL;
4751
4752 rp = _edje_real_part_recursive_get(&ed, part);
4753 if (!rp) return NULL;
4754 if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
4755
4756 r = _edje_real_part_box_remove_at(ed, rp, pos);
4757
4758 if (r) _edje_part_box_remove_user_definition(ed, part, r);
4759 return r;
4760 }
4761
4762 Evas_Object *
_edje_part_box_content_at(Edje * ed,const char * part,unsigned int pos)4763 _edje_part_box_content_at(Edje *ed, const char *part, unsigned int pos)
4764 {
4765 Edje_Real_Part *rp;
4766 Evas_Object *r;
4767
4768 if ((!ed) || (!part)) return NULL;
4769
4770 rp = _edje_real_part_recursive_get(&ed, part);
4771 if (!rp) return NULL;
4772 if (rp->part->type != EDJE_PART_TYPE_BOX) return NULL;
4773
4774 r = _edje_real_part_box_content_at(ed, rp, pos);
4775 return r;
4776 }
4777
4778 Eina_Bool
_edje_part_box_remove_all(Edje * ed,const char * part,Eina_Bool clear)4779 _edje_part_box_remove_all(Edje *ed, const char *part, Eina_Bool clear)
4780 {
4781 Eina_Bool ret;
4782 Edje_Real_Part *rp;
4783 ret = EINA_FALSE;
4784
4785 if ((!ed) || (!part)) return ret;
4786
4787 rp = _edje_real_part_recursive_get(&ed, part);
4788 if (!rp) return ret;
4789 if (rp->part->type != EDJE_PART_TYPE_BOX) return ret;
4790
4791 if (_edje_real_part_box_remove_all(ed, rp, clear))
4792 {
4793 ret = EINA_TRUE;
4794 eina_hash_del_by_key(ed->user_defined, part);
4795 }
4796
4797 return ret;
4798 }
4799
4800 typedef struct _Part_Iterator Part_Iterator;
4801 struct _Part_Iterator
4802 {
4803 Eina_Iterator iterator;
4804 Eo *object;
4805 Edje *ed;
4806 unsigned index;
4807 };
4808
4809 static Eina_Bool
_part_iterator_next(Part_Iterator * it,void ** data)4810 _part_iterator_next(Part_Iterator *it, void **data)
4811 {
4812 for (; it->index < it->ed->table_parts_size; it->index++)
4813 {
4814 Edje_Real_Part *rp = it->ed->table_parts[it->index];
4815 if (rp->part->access)
4816 {
4817 if (data) *data = (void*) rp->part->name;
4818 it->index++;
4819 return EINA_TRUE;
4820 }
4821 }
4822
4823 return EINA_FALSE;
4824 }
4825
4826 static Eo *
_part_iterator_get_container(Part_Iterator * it)4827 _part_iterator_get_container(Part_Iterator *it)
4828 {
4829 return it->object;
4830 }
4831
4832 static void
_part_iterator_free(Part_Iterator * it)4833 _part_iterator_free(Part_Iterator *it)
4834 {
4835 free(it);
4836 }
4837
4838 EOLIAN Eina_Iterator *
_efl_canvas_layout_access_part_iterate(Eo * obj EINA_UNUSED,Edje * ed)4839 _efl_canvas_layout_access_part_iterate(Eo *obj EINA_UNUSED, Edje *ed)
4840 {
4841 Part_Iterator *it;
4842
4843 it = calloc(1, sizeof(*it));
4844 if (!it) return NULL;
4845
4846 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
4847
4848 it->iterator.version = EINA_ITERATOR_VERSION;
4849 it->iterator.next = FUNC_ITERATOR_NEXT(_part_iterator_next);
4850 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_part_iterator_get_container);
4851 it->iterator.free = FUNC_ITERATOR_FREE(_part_iterator_free);
4852 it->object = obj;
4853 it->ed = ed;
4854 it->index = 0;
4855
4856 return &it->iterator;
4857 }
4858
4859 EAPI Eina_List *
edje_object_access_part_list_get(const Edje_Object * obj)4860 edje_object_access_part_list_get(const Edje_Object *obj)
4861 {
4862 Eina_List *access_parts = NULL;
4863 Eina_Iterator *it;
4864 const char *str;
4865
4866 it = efl_canvas_layout_access_part_iterate((Eo *) obj);
4867 EINA_ITERATOR_FOREACH(it, str)
4868 access_parts = eina_list_append(access_parts, str);
4869 eina_iterator_free(it);
4870
4871 return access_parts;
4872 }
4873
4874 static void
_edje_child_del_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * child,void * einfo EINA_UNUSED)4875 _edje_child_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child, void *einfo EINA_UNUSED)
4876 {
4877 Edje_Real_Part *rp = data;
4878 Edje_User_Defined *eud;
4879 Eina_List *l, *ll;
4880 Edje *ed = evas_object_data_get(child, ".edje");
4881
4882 if (!ed) return;
4883 l = eina_hash_find(ed->user_defined, rp->part->name);
4884 EINA_LIST_FOREACH(l, ll, eud)
4885 if (rp->part->type == EDJE_PART_TYPE_BOX)
4886 {
4887 if (eud->type == EDJE_USER_BOX_PACK &&
4888 eud->u.box.child == child)
4889 {
4890 _edje_user_definition_free(eud);
4891 break;
4892 }
4893 }
4894 else if (rp->part->type == EDJE_PART_TYPE_TABLE)
4895 {
4896 if (eud->type == EDJE_USER_TABLE_PACK &&
4897 eud->u.table.child == child)
4898 {
4899 _edje_user_definition_free(eud);
4900 break;
4901 }
4902 }
4903
4904 ed->dirty = EINA_TRUE;
4905 ed->recalc_call = EINA_TRUE;
4906 #ifdef EDJE_CALC_CACHE
4907 rp->invalidate = EINA_TRUE;
4908 #endif
4909 _edje_recalc(ed);
4910 }
4911
4912 static void
_edje_child_add(Edje * ed,Edje_Real_Part * rp,Evas_Object * child)4913 _edje_child_add(Edje *ed, Edje_Real_Part *rp, Evas_Object *child)
4914 {
4915 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _edje_child_del_cb, rp);
4916 evas_object_data_set(child, ".edje", ed);
4917 if (!ed) return;
4918 efl_parent_set(child, ed->obj);
4919 ed->dirty = EINA_TRUE;
4920 ed->recalc_call = EINA_TRUE;
4921 #ifdef EDJE_CALC_CACHE
4922 rp->invalidate = EINA_TRUE;
4923 #endif
4924 _edje_recalc(ed);
4925 }
4926
4927 static void
_eo_unparent_helper(Eo * child,Eo * parent)4928 _eo_unparent_helper(Eo *child, Eo *parent)
4929 {
4930 if (efl_invalidated_get(child)) return ;
4931 if (efl_parent_get(child) == parent)
4932 {
4933 if (efl_invalidated_get(evas_object_evas_get(parent)))
4934 // Temporary reparenting children to the main loop.
4935 // They are about to die, but shouldn't just yet.
4936 {
4937 efl_parent_set(child, efl_main_loop_get());
4938 }
4939 else
4940 {
4941 efl_parent_set(child, evas_object_evas_get(parent));
4942 }
4943 }
4944 }
4945
4946 static void
_edje_child_remove(Edje * ed,Edje_Real_Part * rp,Evas_Object * child)4947 _edje_child_remove(Edje *ed, Edje_Real_Part *rp, Evas_Object *child)
4948 {
4949 evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _edje_child_del_cb, rp);
4950 evas_object_data_del(child, ".edje");
4951 if (!ed) return;
4952 _eo_unparent_helper(child, ed->obj);
4953 ed->dirty = EINA_TRUE;
4954 ed->recalc_call = EINA_TRUE;
4955 #ifdef EDJE_CALC_CACHE
4956 rp->invalidate = EINA_TRUE;
4957 #endif
4958 _edje_recalc(ed);
4959 }
4960
4961 Eina_Bool
_edje_real_part_box_append(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj)4962 _edje_real_part_box_append(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
4963 {
4964 Evas_Object_Box_Option *opt;
4965
4966 opt = evas_object_box_append(rp->object, child_obj);
4967 if (!opt) return EINA_FALSE;
4968
4969 if (!_edje_box_layout_add_child(rp, child_obj))
4970 {
4971 evas_object_box_remove(rp->object, child_obj);
4972 return EINA_FALSE;
4973 }
4974
4975 _edje_child_add(ed, rp, child_obj);
4976
4977 return EINA_TRUE;
4978 }
4979
4980 Eina_Bool
_edje_real_part_box_prepend(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj)4981 _edje_real_part_box_prepend(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
4982 {
4983 Evas_Object_Box_Option *opt;
4984
4985 opt = evas_object_box_prepend(rp->object, child_obj);
4986 if (!opt) return EINA_FALSE;
4987
4988 if (!_edje_box_layout_add_child(rp, child_obj))
4989 {
4990 evas_object_box_remove(rp->object, child_obj);
4991 return EINA_FALSE;
4992 }
4993
4994 _edje_child_add(ed, rp, child_obj);
4995
4996 return EINA_TRUE;
4997 }
4998
4999 Eina_Bool
_edje_real_part_box_insert_before(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj,const Evas_Object * ref)5000 _edje_real_part_box_insert_before(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, const Evas_Object *ref)
5001 {
5002 Evas_Object_Box_Option *opt;
5003
5004 opt = evas_object_box_insert_before(rp->object, child_obj, ref);
5005 if (!opt) return EINA_FALSE;
5006
5007 if (!_edje_box_layout_add_child(rp, child_obj))
5008 {
5009 evas_object_box_remove(rp->object, child_obj);
5010 return EINA_FALSE;
5011 }
5012
5013 _edje_child_add(ed, rp, child_obj);
5014
5015 return EINA_TRUE;
5016 }
5017
5018 Eina_Bool
_edje_real_part_box_insert_after(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj,const Evas_Object * ref)5019 _edje_real_part_box_insert_after(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, const Evas_Object *ref)
5020 {
5021 Evas_Object_Box_Option *opt;
5022
5023 opt = evas_object_box_insert_after(rp->object, child_obj, ref);
5024 if (!opt) return EINA_FALSE;
5025
5026 if (!_edje_box_layout_add_child(rp, child_obj))
5027 {
5028 evas_object_box_remove(rp->object, child_obj);
5029 return EINA_FALSE;
5030 }
5031
5032 _edje_child_add(ed, rp, child_obj);
5033
5034 return EINA_TRUE;
5035 }
5036
5037 Eina_Bool
_edje_real_part_box_insert_at(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj,unsigned int pos)5038 _edje_real_part_box_insert_at(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, unsigned int pos)
5039 {
5040 Evas_Object_Box_Option *opt;
5041
5042 opt = evas_object_box_insert_at(rp->object, child_obj, pos);
5043 if (!opt) return EINA_FALSE;
5044
5045 if (!_edje_box_layout_add_child(rp, child_obj))
5046 {
5047 evas_object_box_remove(rp->object, child_obj);
5048 return EINA_FALSE;
5049 }
5050
5051 _edje_child_add(ed, rp, child_obj);
5052
5053 return EINA_TRUE;
5054 }
5055
5056 Evas_Object *
_edje_real_part_box_content_at(Edje * ed EINA_UNUSED,Edje_Real_Part * rp,unsigned int pos)5057 _edje_real_part_box_content_at(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, unsigned int pos)
5058 {
5059 Evas_Object_Box_Option *opt;
5060 Evas_Object_Box_Data *priv;
5061
5062 priv = efl_data_scope_get(rp->object, EVAS_BOX_CLASS);
5063 opt = eina_list_nth(priv->children, pos);
5064 if (!opt) return NULL;
5065 return opt->obj;
5066 }
5067
5068 Evas_Object *
_edje_real_part_box_remove(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj)5069 _edje_real_part_box_remove(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
5070 {
5071 if (evas_object_data_get(child_obj, "\377 edje.box_item")) return NULL;
5072 if (!evas_object_box_remove(rp->object, child_obj)) return NULL;
5073 _edje_box_layout_remove_child(rp, child_obj);
5074 _edje_child_remove(ed, rp, child_obj);
5075 return child_obj;
5076 }
5077
5078 Evas_Object *
_edje_real_part_box_remove_at(Edje * ed,Edje_Real_Part * rp,unsigned int pos)5079 _edje_real_part_box_remove_at(Edje *ed, Edje_Real_Part *rp, unsigned int pos)
5080 {
5081 Evas_Object_Box_Option *opt;
5082 Evas_Object_Box_Data *priv;
5083 Evas_Object *child_obj;
5084
5085 priv = efl_data_scope_get(rp->object, EVAS_BOX_CLASS);
5086 opt = eina_list_nth(priv->children, pos);
5087 if (!opt) return NULL;
5088 child_obj = opt->obj;
5089 if (evas_object_data_get(child_obj, "\377 edje.box_item")) return NULL;
5090 if (!evas_object_box_remove_at(rp->object, pos)) return NULL;
5091 _edje_box_layout_remove_child(rp, child_obj);
5092 _edje_child_remove(ed, rp, child_obj);
5093 return child_obj;
5094 }
5095
5096 Eina_Bool
_edje_real_part_box_remove_all(Edje * ed,Edje_Real_Part * rp,Eina_Bool clear)5097 _edje_real_part_box_remove_all(Edje *ed, Edje_Real_Part *rp, Eina_Bool clear)
5098 {
5099 Eina_List *children;
5100 int i = 0;
5101
5102 children = evas_object_box_children_get(rp->object);
5103 while (children)
5104 {
5105 Evas_Object *child_obj = children->data;
5106 if (evas_object_data_get(child_obj, "\377 edje.box_item"))
5107 i++;
5108 else
5109 {
5110 _edje_box_layout_remove_child(rp, child_obj);
5111 _edje_child_remove(ed, rp, child_obj);
5112 if (!evas_object_box_remove_at(rp->object, i))
5113 {
5114 eina_list_free(children);
5115 return EINA_FALSE;
5116 }
5117 if (clear)
5118 evas_object_del(child_obj);
5119 }
5120 children = eina_list_remove_list(children, children);
5121 }
5122 return EINA_TRUE;
5123 }
5124
5125 Evas_Object *
_edje_part_table_child_get(Edje * ed,const char * part,unsigned int col,unsigned int row)5126 _edje_part_table_child_get(Edje *ed, const char *part, unsigned int col, unsigned int row)
5127 {
5128 Edje_Real_Part *rp;
5129
5130 if ((!ed) || (!part)) return NULL;
5131
5132 rp = _edje_real_part_recursive_get(&ed, part);
5133 if (!rp) return NULL;
5134 if (rp->part->type != EDJE_PART_TYPE_TABLE) return NULL;
5135
5136 return evas_object_table_child_get(rp->object, col, row);
5137 }
5138
5139 Eina_Bool
_edje_part_table_pack(Edje * ed,const char * part,Evas_Object * child_obj,unsigned short col,unsigned short row,unsigned short colspan,unsigned short rowspan)5140 _edje_part_table_pack(Edje *ed, const char *part, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
5141 {
5142 Eina_Bool ret;
5143 Edje_Real_Part *rp = NULL;
5144 Edje_User_Defined *eud;
5145 ret = EINA_FALSE;
5146
5147 if ((!ed) || (!part)) return ret;
5148
5149 if (ed->file)
5150 {
5151 rp = _edje_real_part_recursive_get(&ed, part);
5152 if (!rp) return ret;
5153 if (rp->part->type != EDJE_PART_TYPE_TABLE) return ret;
5154 }
5155
5156 if ((!ed->file) || _edje_real_part_table_pack(ed, rp, child_obj, col, row, colspan, rowspan))
5157 {
5158 ret = EINA_TRUE;
5159 eud = _edje_user_definition_new(EDJE_USER_TABLE_PACK, part, ed);
5160 if (!eud) return ret;
5161
5162 eud->u.table.child = child_obj;
5163 eud->u.table.col = col;
5164 eud->u.table.row = row;
5165 eud->u.table.colspan = colspan;
5166 eud->u.table.rowspan = rowspan;
5167
5168 evas_object_event_callback_add(child_obj, EVAS_CALLBACK_DEL, _edje_user_def_del_cb, eud);
5169 }
5170
5171 return ret;
5172 }
5173
5174 Eina_Bool
_edje_part_table_unpack(Edje * ed,const char * part,Evas_Object * child_obj)5175 _edje_part_table_unpack(Edje *ed, const char *part, Evas_Object *child_obj)
5176 {
5177 Eina_Bool ret;
5178 Edje_Real_Part *rp;
5179 ret = EINA_FALSE;
5180
5181 if ((!ed) || (!part)) return ret;
5182
5183 rp = _edje_real_part_recursive_get(&ed, part);
5184 if (!rp) return ret;
5185 if (rp->part->type != EDJE_PART_TYPE_TABLE) return ret;
5186
5187 if (_edje_real_part_table_unpack(ed, rp, child_obj))
5188 {
5189 ret = EINA_TRUE;
5190 Edje_User_Defined *eud;
5191 Eina_List *l, *ll;
5192
5193 l = eina_hash_find(ed->user_defined, part);
5194 EINA_LIST_FOREACH(l, ll, eud)
5195 if (eud->type == EDJE_USER_TABLE_PACK &&
5196 eud->u.table.child == child_obj)
5197 {
5198 _edje_user_definition_free(eud);
5199 break;
5200 }
5201 }
5202
5203 return ret;
5204 }
5205
5206 Eina_Bool
_edje_part_table_col_row_size_get(Edje * ed,const char * part,int * cols,int * rows)5207 _edje_part_table_col_row_size_get(Edje *ed, const char *part, int *cols, int *rows)
5208 {
5209 Edje_Real_Part *rp;
5210
5211 if ((!ed) || (!part)) return EINA_FALSE;
5212
5213 rp = _edje_real_part_recursive_get(&ed, part);
5214 if (!rp) return EINA_FALSE;
5215 if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
5216
5217 evas_object_table_col_row_size_get(rp->object, cols, rows);
5218
5219 return EINA_TRUE;
5220 }
5221
5222 Eina_Bool
_edje_part_table_clear(Edje * ed,const char * part,Eina_Bool clear)5223 _edje_part_table_clear(Edje *ed, const char *part, Eina_Bool clear)
5224 {
5225 Edje_Real_Part *rp;
5226
5227 if ((!ed) || (!part)) return EINA_FALSE;
5228
5229 rp = _edje_real_part_recursive_get(&ed, part);
5230 if (!rp) return EINA_FALSE;
5231 if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE;
5232
5233 _edje_real_part_table_clear(ed, rp, clear);
5234
5235 return EINA_TRUE;
5236 }
5237
5238 static void
_edje_perspective_obj_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)5239 _edje_perspective_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
5240 {
5241 Edje_Perspective *ps = data;
5242 Evas_Object *o;
5243
5244 EINA_LIST_FREE(ps->users, o)
5245 {
5246 Edje *ed;
5247
5248 ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
5249 if (!ed) continue;
5250 ed->persp = NULL;
5251 ed->dirty = EINA_TRUE;
5252 ed->recalc_call = EINA_TRUE;
5253 _edje_recalc_do(ed);
5254 }
5255 free(ps);
5256 }
5257
5258 EAPI Edje_Perspective *
edje_perspective_new(Evas * e)5259 edje_perspective_new(Evas *e)
5260 {
5261 Edje_Perspective *ps;
5262 Evas_Coord vx, vy, vw, vh;
5263
5264 if (!e) return NULL;
5265 ps = calloc(1, sizeof(Edje_Perspective));
5266 ps->obj = evas_object_rectangle_add(e);
5267 evas_object_data_set(ps->obj, "_edje_perspective", ps);
5268 evas_object_event_callback_add(ps->obj, EVAS_CALLBACK_DEL, _edje_perspective_obj_del, ps);
5269 evas_output_viewport_get(e, &vx, &vy, &vw, &vh);
5270 ps->e = e;
5271 ps->px = vx + (vw / 2);
5272 ps->py = vy + (vh / 2);
5273 ps->z0 = 0;
5274 ps->foc = 1000;
5275 return ps;
5276 }
5277
5278 EAPI void
edje_perspective_free(Edje_Perspective * ps)5279 edje_perspective_free(Edje_Perspective *ps)
5280 {
5281 if (!ps) return;
5282 evas_object_del(ps->obj);
5283 }
5284
5285 EAPI void
edje_perspective_set(Edje_Perspective * ps,Evas_Coord px,Evas_Coord py,Evas_Coord z0,Evas_Coord foc)5286 edje_perspective_set(Edje_Perspective *ps, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc)
5287 {
5288 Eina_List *l;
5289 Evas_Object *o;
5290
5291 if (!ps) return;
5292 if ((ps->px == px) && (ps->py == py) && (ps->z0 == z0) && (ps->foc == foc)) return;
5293 ps->px = px;
5294 ps->py = py;
5295 ps->z0 = z0;
5296 ps->foc = foc;
5297 EINA_LIST_FOREACH(ps->users, l, o)
5298 {
5299 Edje *ed;
5300
5301 ed = efl_data_scope_get(o, EFL_CANVAS_LAYOUT_CLASS);
5302 if (!ed) continue;
5303 if (!ed->persp)
5304 {
5305 ed->dirty = EINA_TRUE;
5306 ed->recalc_call = EINA_TRUE;
5307 _edje_recalc_do(ed);
5308 }
5309 }
5310 if (ps->global)
5311 {
5312 Edje *ed;
5313
5314 EINA_INLIST_FOREACH(_edje_edjes, ed)
5315 {
5316 if (!ed->persp)
5317 {
5318 ed->dirty = EINA_TRUE;
5319 ed->recalc_call = EINA_TRUE;
5320 _edje_recalc_do(ed);
5321 }
5322 }
5323 }
5324 }
5325
5326 EAPI void
edje_perspective_global_set(Edje_Perspective * ps,Eina_Bool global)5327 edje_perspective_global_set(Edje_Perspective *ps, Eina_Bool global)
5328 {
5329 Edje *ed;
5330 Evas_Object *o;
5331
5332 if (!ps) return;
5333 if (ps->global == global) return;
5334 if (global)
5335 {
5336 o = evas_object_name_find(evas_object_evas_get(ps->obj),
5337 "_edje_perspective");
5338 if (o) evas_object_name_set(o, NULL);
5339 evas_object_name_set(ps->obj, "_edje_perspective");
5340 }
5341 else
5342 evas_object_name_set(ps->obj, NULL);
5343 ps->global = global;
5344 EINA_INLIST_FOREACH(_edje_edjes, ed)
5345 {
5346 if (!ed->persp)
5347 {
5348 ed->dirty = EINA_TRUE;
5349 ed->recalc_call = EINA_TRUE;
5350 _edje_recalc_do(ed);
5351 }
5352 }
5353 }
5354
5355 EAPI Eina_Bool
edje_perspective_global_get(const Edje_Perspective * ps)5356 edje_perspective_global_get(const Edje_Perspective *ps)
5357 {
5358 if (!ps) return EINA_FALSE;
5359 return ps->global;
5360 }
5361
5362 EAPI const Edje_Perspective *
edje_evas_global_perspective_get(const Evas * e)5363 edje_evas_global_perspective_get(const Evas *e)
5364 {
5365 Evas_Object *obj;
5366
5367 if (!e) return NULL;
5368 obj = evas_object_name_find(e, "_edje_perspective");
5369 if (!obj) return NULL;
5370 return evas_object_data_get(obj, "_edje_perspective");
5371 }
5372
5373 EAPI void
edje_object_perspective_set(Eo * obj,Edje_Perspective * ps)5374 edje_object_perspective_set(Eo *obj, Edje_Perspective *ps)
5375 {
5376 Edje *ed = _edje_fetch(obj);
5377 if (!ed) return;
5378 if (ed->persp == ps) return;
5379 if (ed->persp != ps)
5380 {
5381 if (ed->persp)
5382 ed->persp->users = eina_list_remove(ed->persp->users, obj);
5383 }
5384 ed->persp = ps;
5385 if (ps) ps->users = eina_list_append(ps->users, obj);
5386 ed->dirty = EINA_TRUE;
5387 ed->recalc_call = EINA_TRUE;
5388 _edje_recalc_do(ed);
5389 }
5390
5391 EAPI const Edje_Perspective *
edje_object_perspective_get(const Eo * obj)5392 edje_object_perspective_get(const Eo *obj)
5393 {
5394 Edje *ed =_edje_fetch(obj);
5395 if (!ed) return NULL;
5396 return ed->persp;
5397 }
5398
5399 #define EDJE_PRELOAD_EMISSION "preload,done"
5400 #define EDJE_PRELOAD_SOURCE NULL
5401
5402 EAPI Eina_Bool
edje_object_preload(Eo * obj,Eina_Bool cancel)5403 edje_object_preload(Eo *obj, Eina_Bool cancel)
5404 {
5405 unsigned short count;
5406 unsigned short i;
5407 Edje *ed;
5408
5409 ed = _edje_fetch(obj);
5410 if (!ed) return EINA_FALSE;
5411
5412 _edje_recalc_do(ed);
5413
5414 for (i = 0, count = 0; i < ed->table_parts_size; i++)
5415 {
5416 Edje_Real_Part *rp;
5417 Edje_Part *ep;
5418
5419 rp = ed->table_parts[i];
5420 ep = rp->part;
5421
5422 if ((ep->type == EDJE_PART_TYPE_IMAGE) ||
5423 ((ep->type == EDJE_PART_TYPE_GROUP) &&
5424 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
5425 (rp->typedata.swallow)) &&
5426 (rp->typedata.swallow->swallowed_object)))
5427 count++;
5428 }
5429
5430 ed->preload_count = count;
5431
5432 if (count > 0)
5433 {
5434 for (i = 0; i < ed->table_parts_size; i++)
5435 {
5436 Edje_Real_Part *rp;
5437 Edje_Part *ep;
5438
5439 rp = ed->table_parts[i];
5440 ep = rp->part;
5441
5442 if (ep->type == EDJE_PART_TYPE_IMAGE)
5443 {
5444 const char *file = NULL;
5445 const char *key = NULL;
5446
5447 evas_object_event_callback_del_full(rp->object, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
5448
5449 evas_object_image_file_get(rp->object, &file, &key);
5450 if (!file && !key)
5451 {
5452 ed->preload_count--;
5453 }
5454 else
5455 {
5456 evas_object_event_callback_add(rp->object, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
5457 evas_object_image_preload(rp->object, cancel);
5458 }
5459 count--;
5460 }
5461 else if (ep->type == EDJE_PART_TYPE_GROUP)
5462 {
5463 if (((rp->type == EDJE_RP_TYPE_SWALLOW) &&
5464 (rp->typedata.swallow)) &&
5465 (rp->typedata.swallow->swallowed_object))
5466 {
5467 char *tmp;
5468
5469 if (rp->part->name)
5470 {
5471 tmp = alloca(strlen(rp->part->name) + 2);
5472 sprintf(tmp, "%s:", rp->part->name);
5473
5474 edje_object_signal_callback_del(obj, EDJE_PRELOAD_EMISSION, tmp, _edje_object_signal_preload_cb);
5475 edje_object_signal_callback_add(obj, EDJE_PRELOAD_EMISSION, tmp, _edje_object_signal_preload_cb, ed);
5476 edje_object_preload(rp->typedata.swallow->swallowed_object, cancel);
5477 }
5478 else
5479 {
5480 ed->preload_count--;
5481 }
5482 count--;
5483 }
5484 }
5485 }
5486 }
5487 else
5488 {
5489 _edje_emit(ed, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE);
5490 }
5491
5492 return EINA_TRUE;
5493 }
5494
5495 EOLIAN void
_efl_canvas_layout_efl_layout_calc_calc_auto_update_hints_set(Eo * obj EINA_UNUSED,Edje * ed,Eina_Bool update)5496 _efl_canvas_layout_efl_layout_calc_calc_auto_update_hints_set(Eo *obj EINA_UNUSED, Edje *ed, Eina_Bool update)
5497 {
5498 if (!ed) return;
5499 if (ed->update_hints == !!update) return;
5500
5501 ed->update_hints = !!update;
5502 if (update)
5503 {
5504 ed->recalc_hints = EINA_TRUE;
5505 _edje_recalc(ed);
5506 }
5507 }
5508
5509 EOLIAN Eina_Bool
_efl_canvas_layout_efl_layout_calc_calc_auto_update_hints_get(const Eo * obj EINA_UNUSED,Edje * ed)5510 _efl_canvas_layout_efl_layout_calc_calc_auto_update_hints_get(const Eo *obj EINA_UNUSED, Edje *ed)
5511 {
5512 return ed->update_hints;
5513 }
5514
5515 Eina_Bool
_edje_real_part_table_pack(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj,unsigned short col,unsigned short row,unsigned short colspan,unsigned short rowspan)5516 _edje_real_part_table_pack(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
5517 {
5518 Eina_Bool ret =
5519 evas_object_table_pack(rp->object, child_obj, col, row, colspan, rowspan);
5520
5521 _edje_child_add(ed, rp, child_obj);
5522
5523 return ret;
5524 }
5525
5526 Eina_Bool
_edje_real_part_table_unpack(Edje * ed,Edje_Real_Part * rp,Evas_Object * child_obj)5527 _edje_real_part_table_unpack(Edje *ed, Edje_Real_Part *rp, Evas_Object *child_obj)
5528 {
5529 Eina_Bool ret = evas_object_table_unpack(rp->object, child_obj);
5530
5531 if (ret)
5532 _edje_child_remove(ed, rp, child_obj);
5533
5534 return ret;
5535 }
5536
5537 void
_edje_real_part_table_clear(Edje * ed,Edje_Real_Part * rp,Eina_Bool clear)5538 _edje_real_part_table_clear(Edje *ed, Edje_Real_Part *rp, Eina_Bool clear)
5539 {
5540 Eina_List *children;
5541
5542 children = evas_object_table_children_get(rp->object);
5543 while (children)
5544 {
5545 Evas_Object *child_obj = children->data;
5546
5547 _edje_child_remove(ed, rp, child_obj);
5548 if (!evas_object_data_get(child_obj, "\377 edje.table_item"))
5549 {
5550 evas_object_table_unpack(rp->object, child_obj);
5551 if (clear)
5552 evas_object_del(child_obj);
5553 }
5554 children = eina_list_remove_list(children, children);
5555 }
5556 }
5557
5558 Edje_Part_Description_Text *
_edje_real_part_text_source_description_get(Edje_Real_Part * ep,Edje_Real_Part ** rp2)5559 _edje_real_part_text_source_description_get(Edje_Real_Part *ep, Edje_Real_Part **rp2)
5560 {
5561 Edje_Part_Description_Text *et;
5562 Edje_Real_Part *rp = ep->typedata.text->source;
5563 if (ep->typedata.text->source->type == EDJE_RP_TYPE_SWALLOW)
5564 {
5565 Edje *ed2;
5566
5567 et = (Edje_Part_Description_Text *)ep->param1.description;
5568 ed2 = _edje_fetch(ep->typedata.text->source->typedata.swallow->swallowed_object);
5569 if (!ed2) return NULL;
5570 rp = _edje_real_part_recursive_get(&ed2, et->text.id_source_part);
5571 if (!rp) return NULL;
5572 et = (Edje_Part_Description_Text *)rp->chosen_description;
5573 }
5574 else
5575 et = (Edje_Part_Description_Text *)ep->typedata.text->source->chosen_description;
5576 if (rp2) *rp2 = rp;
5577 return et;
5578 }
5579
5580 Edje_Part_Description_Text *
_edje_real_part_text_text_source_description_get(Edje_Real_Part * ep,Edje_Real_Part ** rp2)5581 _edje_real_part_text_text_source_description_get(Edje_Real_Part *ep, Edje_Real_Part **rp2)
5582 {
5583 Edje_Part_Description_Text *et;
5584 Edje_Real_Part *rp = ep->typedata.text->text_source;
5585 if (ep->typedata.text->text_source->type == EDJE_RP_TYPE_SWALLOW)
5586 {
5587 Edje *ed2;
5588
5589 et = (Edje_Part_Description_Text *)ep->param1.description;
5590 ed2 = _edje_fetch(ep->typedata.text->text_source->typedata.swallow->swallowed_object);
5591 if (!ed2) return NULL;
5592 rp = _edje_real_part_recursive_get(&ed2, et->text.id_text_source_part);
5593 if (!rp) return NULL;
5594 et = (Edje_Part_Description_Text *)rp->chosen_description;
5595 }
5596 else
5597 et = (Edje_Part_Description_Text *)ep->typedata.text->text_source->chosen_description;
5598 if (rp2) *rp2 = rp;
5599 return et;
5600 }
5601
5602 Edje_Real_Part *
_edje_real_part_recursive_get(Edje ** ed,const char * part)5603 _edje_real_part_recursive_get(Edje **ed, const char *part)
5604 {
5605 Edje_Real_Part *rp;
5606 char **path;
5607
5608 path = eina_str_split(part, EDJE_PART_PATH_SEPARATOR_STRING, 0);
5609 if (!path) return NULL;
5610
5611 rp = _edje_real_part_recursive_get_helper(ed, path);
5612
5613 free(*path);
5614 free(path);
5615 return rp;
5616 }
5617
5618 Evas_Object *
_edje_children_get(Edje_Real_Part * rp,const char * partid)5619 _edje_children_get(Edje_Real_Part *rp, const char *partid)
5620 {
5621 Evas_Object *child = NULL;
5622 Eina_Iterator *it = NULL;
5623 long int v;
5624 char *p;
5625
5626 if (!partid) return NULL;
5627
5628 switch (rp->part->type)
5629 {
5630 case EDJE_PART_TYPE_EXTERNAL:
5631 if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
5632 (!rp->typedata.swallow)) return NULL;
5633 return _edje_external_content_get
5634 (rp->typedata.swallow->swallowed_object, partid);
5635
5636 case EDJE_PART_TYPE_BOX:
5637 it = evas_object_box_iterator_new(rp->object);
5638 break;
5639
5640 case EDJE_PART_TYPE_TABLE:
5641 it = evas_object_table_iterator_new(rp->object);
5642 break;
5643
5644 default:
5645 return NULL;
5646 }
5647
5648 v = strtol(partid, &p, 10);
5649 if ((*p == '\0') && (v >= 0))
5650 {
5651 int i = 0;
5652 EINA_ITERATOR_FOREACH(it, child)
5653 {
5654 if (i == v) break;
5655 i++;
5656 }
5657 if (i != v) child = NULL;
5658 }
5659 else
5660 {
5661 Evas_Object *cur;
5662
5663 EINA_ITERATOR_FOREACH(it, cur)
5664 {
5665 const char *name = evas_object_name_get(cur);
5666 if ((name) && (!strcmp(name, partid)))
5667 {
5668 child = cur;
5669 break;
5670 }
5671 }
5672 }
5673 eina_iterator_free(it);
5674
5675 return child;
5676 }
5677
5678 /* rebuild alternative path */
5679 char *
_edje_merge_path(const char * alias,char * const * path)5680 _edje_merge_path(const char *alias, char *const *path)
5681 {
5682 char *tmp;
5683 unsigned int length = 1;
5684 unsigned int alias_length;
5685 unsigned int i;
5686
5687 if (!alias) return NULL;
5688
5689 alias_length = strlen(alias);
5690
5691 for (i = 0; path[i]; i++)
5692 length += strlen(path[i]) + 1;
5693
5694 tmp = malloc(sizeof (char) * (length + alias_length + 2));
5695 memcpy(tmp, alias, alias_length);
5696 tmp[alias_length] = '\0';
5697
5698 for (i = 0; path[i]; i++)
5699 {
5700 strcat(tmp, EDJE_PART_PATH_SEPARATOR_STRING);
5701 strcat(tmp, path[i]);
5702 }
5703
5704 return tmp;
5705 }
5706
5707 Edje_Real_Part *
_edje_real_part_recursive_get_helper(Edje ** ed,char ** path)5708 _edje_real_part_recursive_get_helper(Edje **ed, char **path)
5709 {
5710 Edje_Real_Part *rp;
5711 Evas_Object *child;
5712 char *idx = NULL;
5713
5714 if (!path[0])
5715 return NULL;
5716
5717 if ((*ed)->collection && (*ed)->collection->alias)
5718 {
5719 char *alias;
5720
5721 alias = _edje_merge_path(eina_hash_find((*ed)->collection->alias, path[0]), path + 1);
5722 if (alias)
5723 {
5724 rp = _edje_real_part_recursive_get(ed, alias);
5725 free(alias);
5726 return rp;
5727 }
5728 }
5729
5730 //printf(" lookup: %s on %s\n", path[0], ed->parent ? ed->parent : "-");
5731 idx = strchr(path[0], EDJE_PART_PATH_SEPARATOR_INDEXL);
5732 if (idx)
5733 {
5734 char *end;
5735
5736 end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR);
5737 if (end)
5738 {
5739 *end = '\0';
5740 *idx = '\0';
5741 idx++;
5742 }
5743 }
5744
5745 rp = _edje_real_part_get(*ed, path[0]);
5746 if (!path[1] && !idx) return rp;
5747 if (!rp) return NULL;
5748
5749 switch (rp->part->type)
5750 {
5751 case EDJE_PART_TYPE_GROUP:
5752 if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
5753 (!rp->typedata.swallow)) return NULL;
5754 if (!rp->typedata.swallow->swallowed_object) return NULL;
5755 *ed = _edje_fetch(rp->typedata.swallow->swallowed_object);
5756 if (!*ed) return NULL;
5757 path++;
5758 return _edje_real_part_recursive_get_helper(ed, path);
5759
5760 case EDJE_PART_TYPE_BOX:
5761 case EDJE_PART_TYPE_TABLE:
5762 case EDJE_PART_TYPE_EXTERNAL:
5763 if (!idx) return rp;
5764 path++;
5765
5766 child = _edje_children_get(rp, idx);
5767
5768 *ed = _edje_fetch(child);
5769
5770 if (!*ed) return NULL;
5771 return _edje_real_part_recursive_get_helper(ed, path);
5772
5773 default:
5774 return NULL;
5775 }
5776 }
5777
5778 /* Private Routines - do not call eo_do inside this one */
5779 Edje_Real_Part *
_edje_real_part_get(const Edje * ed,const char * part)5780 _edje_real_part_get(const Edje *ed, const char *part)
5781 {
5782 unsigned short i;
5783
5784 if (!part) return NULL;
5785
5786 for (i = 0; i < ed->table_parts_size; i++)
5787 {
5788 Edje_Real_Part *rp;
5789
5790 rp = ed->table_parts[i];
5791 if ((rp->part->name) && (!strcmp(rp->part->name, part))) return rp;
5792 }
5793 return NULL;
5794 }
5795
5796 void *
_edje_hash_find_helper(const Eina_Hash * hash,const char * key)5797 _edje_hash_find_helper(const Eina_Hash *hash, const char *key)
5798 {
5799 static const char *remember_key = NULL;
5800 void *data;
5801 int i, j;
5802 char **tokens;
5803 unsigned int tokens_count = 0;
5804
5805 data = eina_hash_find(hash, key);
5806 if (data)
5807 return data;
5808
5809 // We only receive pointer from Eet files as key, we can
5810 // assume them constant over the life time of the program.
5811 if (remember_key == key)
5812 return NULL;
5813
5814 // It is usually faster to walk the string once to check
5815 // if there will be any tokens to process, that to allocate
5816 // an array, copy one token, and then just free it.
5817 if (strchr(key, '/') == NULL)
5818 {
5819 remember_key = key;
5820 return NULL;
5821 }
5822
5823 tokens = eina_str_split_full(key, "/", 0, &tokens_count);
5824 if ((tokens) && (tokens_count > 1))
5825 {
5826 Eina_Strbuf *buf = NULL;
5827
5828 buf = eina_strbuf_new();
5829
5830 for (i = tokens_count - 2; i >= 0; i--)
5831 {
5832 for (j = 0; j < i; j++)
5833 {
5834 eina_strbuf_append(buf, tokens[j]);
5835 eina_strbuf_append(buf, "/");
5836 }
5837 eina_strbuf_append(buf, tokens[tokens_count - 1]);
5838
5839 data = eina_hash_find(hash, eina_strbuf_string_get(buf));
5840 if (data) break;
5841
5842 eina_strbuf_reset(buf);
5843 }
5844
5845 eina_strbuf_free(buf);
5846 }
5847 else
5848 {
5849 remember_key = key;
5850 }
5851
5852 if (tokens)
5853 {
5854 free(tokens[0]);
5855 free(tokens);
5856 }
5857 return data;
5858 }
5859
5860 Edje_Color_Class *
_edje_color_class_find(const Edje * ed,const char * color_class)5861 _edje_color_class_find(const Edje *ed, const char *color_class)
5862 {
5863 Edje_Color_Class *cc = NULL;
5864
5865 if ((!ed) || (!color_class)) return NULL;
5866
5867 /* first look through the object scope */
5868 cc = eina_hash_find(ed->color_classes, color_class);
5869 if (cc) return cc;
5870
5871 /* next look through the global scope */
5872 cc = eina_hash_find(_edje_color_class_hash, color_class);
5873 if (cc) return cc;
5874
5875 /* finally, look through the file scope */
5876 if (ed->file)
5877 cc = eina_hash_find(ed->file->color_hash, color_class);
5878 if (cc) return cc;
5879
5880 return NULL;
5881 }
5882
5883 Edje_Color_Class *
_edje_color_class_recursive_find_helper(const Edje * ed,Eina_Hash * hash,const char * color_class)5884 _edje_color_class_recursive_find_helper(const Edje *ed, Eina_Hash *hash, const char *color_class)
5885 {
5886 Edje_Color_Class *cc = NULL;
5887 Edje_Color_Tree_Node *ctn = NULL;
5888 const char *parent;
5889
5890 if (!eina_hash_population(hash)) return NULL;
5891
5892 cc = _edje_hash_find_helper(hash, color_class);
5893 if (cc) return cc;
5894 else if (ed->file)
5895 {
5896 parent = color_class;
5897 while ((ctn = eina_hash_find(ed->file->color_tree_hash, parent)))
5898 {
5899 parent = ctn->name;
5900 cc = eina_hash_find(hash, parent);
5901 if (cc) return cc;
5902 }
5903 }
5904 return NULL;
5905 }
5906
5907 Edje_Color_Class *
_edje_color_class_recursive_find(const Edje * ed,const char * color_class)5908 _edje_color_class_recursive_find(const Edje *ed, const char *color_class)
5909 {
5910 Edje_Color_Class *cc = NULL;
5911
5912 if ((!ed) || (!color_class)) return NULL;
5913
5914 /* first look through the object scope */
5915 cc = _edje_color_class_recursive_find_helper(ed, ed->color_classes, color_class);
5916 if (cc) return cc;
5917
5918 /* next look through the global scope */
5919 cc = _edje_color_class_recursive_find_helper(ed, _edje_color_class_hash, color_class);
5920 if (cc) return cc;
5921
5922 /* finally, look through the file scope */
5923 if (ed->file)
5924 cc = _edje_color_class_recursive_find_helper(ed, ed->file->color_hash, color_class);
5925 if (cc) return cc;
5926
5927 return NULL;
5928 }
5929
5930 static Eina_Bool
color_class_hash_list_free(const Eina_Hash * hash EINA_UNUSED,const void * key EINA_UNUSED,void * data,void * fdata EINA_UNUSED)5931 color_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
5932 {
5933 Edje_Color_Class *cc;
5934
5935 cc = data;
5936 if (cc->name) eina_stringshare_del(cc->name);
5937 free(cc);
5938 return EINA_TRUE;
5939 }
5940
5941 void
_edje_color_class_hash_free(void)5942 _edje_color_class_hash_free(void)
5943 {
5944 if (!_edje_color_class_hash) return;
5945 eina_hash_foreach(_edje_color_class_hash, color_class_hash_list_free, NULL);
5946 eina_hash_free(_edje_color_class_hash);
5947 _edje_color_class_hash = NULL;
5948 }
5949
5950 void
_edje_color_class_on_del(Edje * ed,Edje_Part * ep)5951 _edje_color_class_on_del(Edje *ed, Edje_Part *ep)
5952 {
5953 unsigned int i;
5954
5955 if ((ep->default_desc) && (ep->default_desc->color_class))
5956 efl_observable_observer_del(_edje_color_class_member, ep->default_desc->color_class, ed->obj);
5957
5958 for (i = 0; i < ep->other.desc_count; ++i)
5959 if (ep->other.desc[i]->color_class)
5960 efl_observable_observer_del(_edje_color_class_member, ep->other.desc[i]->color_class, ed->obj);
5961 }
5962
5963 Edje_Text_Class *
_edje_text_class_find(Edje * ed,const char * text_class)5964 _edje_text_class_find(Edje *ed, const char *text_class)
5965 {
5966 Edje_Text_Class *tc = NULL;
5967
5968 if (!text_class) return NULL;
5969
5970 if (!ed)
5971 {
5972 /* If ed object is NULL, then look through the global scope only */
5973 return eina_hash_find(_edje_text_class_hash, text_class);
5974 }
5975
5976 /* first look through the object scope */
5977 tc = eina_hash_find(ed->text_classes, text_class);
5978
5979 /* next look through the global scope */
5980 if (!tc)
5981 tc = eina_hash_find(_edje_text_class_hash, text_class);
5982
5983 /* finally, look through the file scope */
5984 if (!tc && ed->file)
5985 tc = eina_hash_find(ed->file->text_hash, text_class);
5986
5987 return tc;
5988 }
5989
5990 static Eina_Bool
text_class_hash_list_free(const Eina_Hash * hash EINA_UNUSED,const void * key EINA_UNUSED,void * data,void * fdata EINA_UNUSED)5991 text_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
5992 {
5993 Edje_Text_Class *tc;
5994
5995 tc = data;
5996 if (tc->name) eina_stringshare_del(tc->name);
5997 if (tc->font) eina_stringshare_del(tc->font);
5998 free(tc);
5999 return EINA_TRUE;
6000 }
6001
6002 void
_edje_text_class_hash_free(void)6003 _edje_text_class_hash_free(void)
6004 {
6005 if (!_edje_text_class_hash) return;
6006 eina_hash_foreach(_edje_text_class_hash, text_class_hash_list_free, NULL);
6007 eina_hash_free(_edje_text_class_hash);
6008 _edje_text_class_hash = NULL;
6009 }
6010
6011 Edje_Size_Class *
_edje_size_class_find(Edje * ed,const char * size_class)6012 _edje_size_class_find(Edje *ed, const char *size_class)
6013 {
6014 Edje_Size_Class *sc;
6015
6016 if ((!ed) || (!size_class)) return NULL;
6017
6018 /* first look through the object scope */
6019 sc = eina_hash_find(ed->size_classes, size_class);
6020 if (sc) return sc;
6021
6022 /* next look through the global scope */
6023 sc = eina_hash_find(_edje_size_class_hash, size_class);
6024 if (sc) return sc;
6025
6026 /* finally, look through the file scope */
6027 if (ed->file)
6028 sc = eina_hash_find(ed->file->size_hash, size_class);
6029 if (sc) return sc;
6030
6031 return NULL;
6032 }
6033
6034 static Eina_Bool
size_class_hash_list_free(const Eina_Hash * hash EINA_UNUSED,const void * key EINA_UNUSED,void * data,void * fdata EINA_UNUSED)6035 size_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
6036 {
6037 Edje_Size_Class *sc;
6038
6039 sc = data;
6040 if (sc->name) eina_stringshare_del(sc->name);
6041 free(sc);
6042 return EINA_TRUE;
6043 }
6044
6045 void
_edje_size_class_hash_free(void)6046 _edje_size_class_hash_free(void)
6047 {
6048 if (!_edje_size_class_hash) return;
6049 eina_hash_foreach(_edje_size_class_hash, size_class_hash_list_free, NULL);
6050 eina_hash_free(_edje_size_class_hash);
6051 _edje_size_class_hash = NULL;
6052 }
6053
6054 Edje *
_edje_fetch(const Evas_Object * obj)6055 _edje_fetch(const Evas_Object *obj)
6056 {
6057 Edje *ed;
6058
6059 if (!obj || !efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
6060 return NULL;
6061 ed = efl_data_scope_get(obj, EFL_CANVAS_LAYOUT_CLASS);
6062 if ((ed) && (ed->delete_me)) return NULL;
6063 return ed;
6064 }
6065
6066 int
_edje_util_freeze(Edje * ed)6067 _edje_util_freeze(Edje *ed)
6068 {
6069 ed->freeze++;
6070 // printf("FREEZE %i\n", ed->freeze);
6071 return ed->freeze;
6072 }
6073
6074 int
_edje_util_thaw(Edje * ed)6075 _edje_util_thaw(Edje *ed)
6076 {
6077 if (ed->freeze == 0) return 0;
6078 ed->freeze--;
6079 if ((ed->freeze == 0) && (ed->recalc))
6080 {
6081 // printf("thaw recalc\n");
6082 _edje_recalc(ed);
6083 }
6084 return ed->freeze;
6085 }
6086
6087 int
_edje_block(Edje * ed)6088 _edje_block(Edje *ed)
6089 {
6090 _edje_ref(ed);
6091 ed->block++;
6092 return ed->block;
6093 }
6094
6095 int
_edje_unblock(Edje * ed)6096 _edje_unblock(Edje *ed)
6097 {
6098 int ret = 0;
6099
6100 if (!ed) return ret;
6101
6102 ed->block--;
6103 if (ed->block == 0) ed->block_break = EINA_FALSE;
6104 ret = ed->block;
6105 _edje_unref(ed);
6106 return ret;
6107 }
6108
6109 int
_edje_block_break(Edje * ed)6110 _edje_block_break(Edje *ed)
6111 {
6112 if (ed->block_break) return 1;
6113 return 0;
6114 }
6115
6116 void
_edje_block_violate(Edje * ed)6117 _edje_block_violate(Edje *ed)
6118 {
6119 if (ed->block > 0) ed->block_break = EINA_TRUE;
6120 }
6121
6122 void
_edje_object_part_swallow_free_cb(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)6123 _edje_object_part_swallow_free_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6124 {
6125 Edje_User_Defined *eud;
6126 Eina_List *l, *ll;
6127 Eina_Iterator *it;
6128 Edje *ed;
6129 Edje_Real_Part *rp;
6130
6131 ed = evas_object_data_get(obj, ".edje");
6132 if (!ed) return;
6133 it = eina_hash_iterator_data_new(ed->user_defined);
6134 EINA_ITERATOR_FOREACH(it, l)
6135 {
6136 EINA_LIST_FOREACH(l, ll, eud)
6137 if (eud->type == EDJE_USER_SWALLOW && eud->u.swallow.child == obj)
6138 {
6139 _edje_user_definition_free(eud);
6140 goto out;
6141 }
6142 }
6143 out:
6144 rp = evas_object_data_get(obj, "\377 edje.swallowing_part");
6145 if (rp && (rp->part->type == EDJE_PART_TYPE_SWALLOW))
6146 edje_object_part_unswallow(ed->obj, obj);
6147
6148 return;
6149 }
6150
6151 static void
_edje_real_part_swallow_hints_update(Edje_Real_Part * rp)6152 _edje_real_part_swallow_hints_update(Edje_Real_Part *rp)
6153 {
6154 if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
6155 (!rp->typedata.swallow)) return;
6156
6157 rp->typedata.swallow->swallow_params.min.w = 0;
6158 rp->typedata.swallow->swallow_params.min.h = 0;
6159 rp->typedata.swallow->swallow_params.max.w = -1;
6160 rp->typedata.swallow->swallow_params.max.h = -1;
6161 if (efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_LAYOUT_CLASS))
6162 {
6163 Evas_Coord w = 0, h = 0;
6164
6165 #if 0
6166 edje_object_size_min_get(rp->typedata.swallow->swallowed_object, &w, &h);
6167 rp->typedata.swallow->swallow_params.min.w = w;
6168 rp->typedata.swallow->swallow_params.min.h = h;
6169 #endif
6170 edje_object_size_max_get(rp->typedata.swallow->swallowed_object, &w, &h);
6171 rp->typedata.swallow->swallow_params.max.w = w;
6172 rp->typedata.swallow->swallow_params.max.h = h;
6173 }
6174 else if (efl_isa(rp->typedata.swallow->swallowed_object, EVAS_TEXT_CLASS) ||
6175 efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_POLYGON_CLASS) ||
6176 efl_isa(rp->typedata.swallow->swallowed_object, EVAS_LINE_CLASS))
6177 {
6178 Evas_Coord w = 0, h = 0;
6179
6180 evas_object_geometry_get(rp->typedata.swallow->swallowed_object, NULL, NULL, &w, &h);
6181 #if 0
6182 rp->typedata.swallow->swallow_params.min.w = w;
6183 rp->typedata.swallow->swallow_params.min.h = h;
6184 #endif
6185 rp->typedata.swallow->swallow_params.max.w = w;
6186 rp->typedata.swallow->swallow_params.max.h = h;
6187 }
6188 {
6189 Evas_Coord w1 = 0, h1 = 0, w2 = 0, h2 = 0, aw = 0, ah = 0;
6190 Evas_Aspect_Control am = EVAS_ASPECT_CONTROL_NONE;
6191
6192 evas_object_size_hint_combined_min_get(rp->typedata.swallow->swallowed_object, &w1, &h1);
6193 evas_object_size_hint_combined_max_get(rp->typedata.swallow->swallowed_object, &w2, &h2);
6194 evas_object_size_hint_aspect_get(rp->typedata.swallow->swallowed_object, &am, &aw, &ah);
6195 rp->typedata.swallow->swallow_params.min.w = w1;
6196 rp->typedata.swallow->swallow_params.min.h = h1;
6197 if (w2 > 0) rp->typedata.swallow->swallow_params.max.w = w2;
6198 if (h2 > 0) rp->typedata.swallow->swallow_params.max.h = h2;
6199 switch (am)
6200 {
6201 case EVAS_ASPECT_CONTROL_NONE:
6202 rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_NONE;
6203 break;
6204
6205 case EVAS_ASPECT_CONTROL_NEITHER:
6206 rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_NEITHER;
6207 break;
6208
6209 case EVAS_ASPECT_CONTROL_HORIZONTAL:
6210 rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_HORIZONTAL;
6211 break;
6212
6213 case EVAS_ASPECT_CONTROL_VERTICAL:
6214 rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_VERTICAL;
6215 break;
6216
6217 case EVAS_ASPECT_CONTROL_BOTH:
6218 rp->typedata.swallow->swallow_params.aspect.mode = EDJE_ASPECT_CONTROL_BOTH;
6219 break;
6220
6221 default:
6222 break;
6223 }
6224 rp->typedata.swallow->swallow_params.aspect.w = aw;
6225 rp->typedata.swallow->swallow_params.aspect.h = ah;
6226 evas_object_data_set(rp->typedata.swallow->swallowed_object, "\377 edje.swallowing_part", rp);
6227 }
6228
6229 #ifdef EDJE_CALC_CACHE
6230 rp->invalidate = EINA_TRUE;
6231 #endif
6232 }
6233
6234 void
_edje_object_part_swallow_changed_hints_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)6235 _edje_object_part_swallow_changed_hints_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6236 {
6237 Edje_Real_Part *rp;
6238 Edje *ed;
6239
6240 rp = data;
6241 ed = evas_object_data_get(obj, ".edje");
6242 if (!ed) return;
6243 _edje_real_part_swallow_hints_update(rp);
6244 ed->dirty = EINA_TRUE;
6245 ed->recalc_call = EINA_TRUE;
6246 ed->recalc_hints = EINA_TRUE;
6247
6248 _edje_recalc(ed);
6249 return;
6250 }
6251
6252 void
_edje_object_part_swallow_image_resize_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)6253 _edje_object_part_swallow_image_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
6254 {
6255 Edje_Real_Part *rp = data;
6256 Evas_Coord w, h;
6257 Evas_Map *map;
6258
6259 if (!rp->chosen_description->map.on) return;
6260 if (rp->type != EDJE_RP_TYPE_SWALLOW) return;
6261 if (!rp->typedata.swallow) return;
6262 if (evas_object_image_source_get(rp->typedata.swallow->swallowed_object))
6263 return;
6264
6265 map = (Evas_Map *)evas_object_map_get(rp->typedata.swallow->swallowed_object);
6266 if (!map) return;
6267
6268 evas_object_image_size_get(rp->typedata.swallow->swallowed_object, &w, &h);
6269 evas_map_point_image_uv_set(map, 0, 0, 0);
6270 evas_map_point_image_uv_set(map, 1, w, 0);
6271 evas_map_point_image_uv_set(map, 2, w, h);
6272 evas_map_point_image_uv_set(map, 3, 0, h);
6273
6274 evas_object_map_set(rp->typedata.swallow->swallowed_object, map);
6275 }
6276
6277 void
_edje_real_part_swallow(Edje * ed,Edje_Real_Part * rp,Evas_Object * obj_swallow,Eina_Bool hints_update)6278 _edje_real_part_swallow(Edje *ed,
6279 Edje_Real_Part *rp,
6280 Evas_Object *obj_swallow,
6281 Eina_Bool hints_update)
6282 {
6283 if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
6284 (!rp->typedata.swallow)) return;
6285 if (rp->typedata.swallow->swallowed_object)
6286 {
6287 if (rp->typedata.swallow->swallowed_object != obj_swallow)
6288 {
6289 edje_object_part_unswallow(ed->obj, rp->typedata.swallow->swallowed_object);
6290 }
6291 else
6292 {
6293 if (hints_update)
6294 _edje_real_part_swallow_hints_update(rp);
6295 ed->dirty = EINA_TRUE;
6296 ed->recalc_call = EINA_TRUE;
6297 ed->recalc_hints = EINA_TRUE;
6298 _edje_recalc(ed);
6299 return;
6300 }
6301 }
6302 #ifdef EDJE_CALC_CACHE
6303 rp->invalidate = EINA_TRUE;
6304 #endif
6305 if (!obj_swallow) return;
6306 rp->typedata.swallow->swallowed_object = obj_swallow;
6307 efl_parent_set(obj_swallow, ed->obj);
6308 evas_object_smart_member_add(rp->typedata.swallow->swallowed_object, ed->obj);
6309 if (rp->part->clip_to_id >= 0)
6310 {
6311 Edje_Real_Part *clip_to;
6312
6313 clip_to = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size];
6314 evas_object_clip_set(rp->typedata.swallow->swallowed_object, clip_to->object);
6315 }
6316 else evas_object_clip_set(rp->typedata.swallow->swallowed_object, ed->base.clipper);
6317 //FIXME: I'm not sure why Edje Nested is a parent of the rp->object here. Is it normal case?
6318 if (evas_object_smart_parent_get(rp->object) == ed->obj)
6319 evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object);
6320 evas_object_event_callback_add(rp->typedata.swallow->swallowed_object,
6321 EVAS_CALLBACK_DEL,
6322 _edje_object_part_swallow_free_cb,
6323 rp);
6324 evas_object_event_callback_add(rp->typedata.swallow->swallowed_object,
6325 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6326 _edje_object_part_swallow_changed_hints_cb,
6327 rp);
6328 evas_object_data_set(rp->typedata.swallow->swallowed_object, ".edje", ed);
6329
6330 //If the map is enabled, uv should be updated when image size is changed.
6331 if (efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_IMAGE_INTERNAL_CLASS))
6332 evas_object_event_callback_add(obj_swallow, EVAS_CALLBACK_IMAGE_RESIZE,
6333 _edje_object_part_swallow_image_resize_cb,
6334 rp);
6335
6336 if (hints_update)
6337 _edje_real_part_swallow_hints_update(rp);
6338
6339 if (rp->mouse_events)
6340 {
6341 _edje_callbacks_add(obj_swallow, ed, rp);
6342 evas_object_repeat_events_set(obj_swallow, rp->repeat_events);
6343 if (rp->part->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB)
6344 evas_object_pointer_mode_set(obj_swallow, rp->part->pointer_mode);
6345 evas_object_pass_events_set(obj_swallow, 0);
6346 }
6347 else
6348 evas_object_pass_events_set(obj_swallow, 1);
6349 _edje_callbacks_focus_add(rp->typedata.swallow->swallowed_object, ed, rp);
6350 efl_canvas_object_anti_alias_set(obj_swallow, rp->part->anti_alias);
6351 efl_canvas_object_precise_is_inside_set(obj_swallow, rp->part->precise_is_inside);
6352
6353 ed->dirty = EINA_TRUE;
6354 ed->recalc_call = EINA_TRUE;
6355 ed->recalc_hints = EINA_TRUE;
6356 _edje_recalc(ed);
6357 }
6358
6359 void
_edje_real_part_swallow_clear(Edje * ed,Edje_Real_Part * rp)6360 _edje_real_part_swallow_clear(Edje *ed, Edje_Real_Part *rp)
6361 {
6362 if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
6363 (!rp->typedata.swallow)) return;
6364 if (!rp->typedata.swallow->swallowed_object) return;
6365 if (rp->chosen_description->map.on ||
6366 (rp->invalidate && rp->prev_description && rp->prev_description->map.on))
6367 {
6368 evas_object_map_enable_set(rp->typedata.swallow->swallowed_object, EINA_FALSE);
6369 }
6370 _eo_unparent_helper(rp->typedata.swallow->swallowed_object, ed->obj);
6371 evas_object_smart_member_del(rp->typedata.swallow->swallowed_object);
6372 evas_object_event_callback_del_full(rp->typedata.swallow->swallowed_object,
6373 EVAS_CALLBACK_DEL,
6374 _edje_object_part_swallow_free_cb,
6375 rp);
6376 evas_object_event_callback_del_full(rp->typedata.swallow->swallowed_object,
6377 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
6378 _edje_object_part_swallow_changed_hints_cb,
6379 rp);
6380 if (efl_isa(rp->typedata.swallow->swallowed_object, EFL_CANVAS_IMAGE_INTERNAL_CLASS))
6381 evas_object_event_callback_del_full(rp->typedata.swallow->swallowed_object,
6382 EVAS_CALLBACK_IMAGE_RESIZE,
6383 _edje_object_part_swallow_image_resize_cb,
6384 rp);
6385 evas_object_clip_unset(rp->typedata.swallow->swallowed_object);
6386 evas_object_data_del(rp->typedata.swallow->swallowed_object, "\377 edje.swallowing_part");
6387 _edje_callbacks_del(rp->typedata.swallow->swallowed_object, ed);
6388 _edje_callbacks_focus_del(rp->typedata.swallow->swallowed_object, ed);
6389 rp->typedata.swallow->swallowed_object = NULL;
6390 }
6391
6392 static void
_edje_object_preload_helper(Edje * ed)6393 _edje_object_preload_helper(Edje *ed)
6394 {
6395 ed->preload_count--;
6396 if (!ed->preload_count)
6397 _edje_emit(ed, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE);
6398 }
6399
6400 static void
_edje_object_image_preload_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)6401 _edje_object_image_preload_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6402 {
6403 Edje *ed = data;
6404
6405 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_IMAGE_PRELOADED, _edje_object_image_preload_cb, ed);
6406 _edje_object_preload_helper(ed);
6407 }
6408
6409 static void
_edje_object_signal_preload_cb(void * data,Evas_Object * obj,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)6410 _edje_object_signal_preload_cb(void *data, Evas_Object *obj, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
6411 {
6412 Edje *ed = data;
6413
6414 edje_object_signal_callback_del(obj, EDJE_PRELOAD_EMISSION, EDJE_PRELOAD_SOURCE, _edje_object_signal_preload_cb);
6415 _edje_object_preload_helper(ed);
6416 }
6417
6418 /**
6419 * @internal
6420 *
6421 * for edje_cc
6422 */
6423 EAPI void
_edje_program_remove(Edje_Part_Collection * edc,Edje_Program * p)6424 _edje_program_remove(Edje_Part_Collection *edc, Edje_Program *p)
6425 {
6426 Edje_Program ***array;
6427 unsigned int *count;
6428 unsigned int i;
6429
6430 if (!p->signal && !p->source)
6431 {
6432 array = &edc->programs.nocmp;
6433 count = &edc->programs.nocmp_count;
6434 }
6435 else if (p->signal && !strpbrk(p->signal, "*?[\\")
6436 && p->source && !strpbrk(p->source, "*?[\\"))
6437 {
6438 array = &edc->programs.strcmp;
6439 count = &edc->programs.strcmp_count;
6440 }
6441 else if (p->signal && edje_program_is_strncmp(p->signal)
6442 && p->source && edje_program_is_strncmp(p->source))
6443 {
6444 array = &edc->programs.strncmp;
6445 count = &edc->programs.strncmp_count;
6446 }
6447 else if (p->signal && edje_program_is_strrncmp(p->signal)
6448 && p->source && edje_program_is_strrncmp(p->source))
6449 {
6450 array = &edc->programs.strrncmp;
6451 count = &edc->programs.strrncmp_count;
6452 }
6453 else
6454 {
6455 array = &edc->programs.fnmatch;
6456 count = &edc->programs.fnmatch_count;
6457 }
6458
6459 for (i = 0; i < *count; ++i)
6460 if ((*array)[i] == p)
6461 {
6462 memmove(*array + i, *array + i + 1, sizeof (Edje_Program *) * (*count - i - 1));
6463 (*count)--;
6464 break;
6465 }
6466 }
6467
6468 /**
6469 * @internal
6470 *
6471 * for edje_cc
6472 */
6473 EAPI void
_edje_program_insert(Edje_Part_Collection * edc,Edje_Program * p)6474 _edje_program_insert(Edje_Part_Collection *edc, Edje_Program *p)
6475 {
6476 Edje_Program ***array, **temp;
6477 unsigned int *count;
6478
6479 if (!p->signal && !p->source)
6480 {
6481 array = &edc->programs.nocmp;
6482 count = &edc->programs.nocmp_count;
6483 }
6484 else if (p->signal && !strpbrk(p->signal, "*?[\\")
6485 && p->source && !strpbrk(p->source, "*?[\\"))
6486 {
6487 array = &edc->programs.strcmp;
6488 count = &edc->programs.strcmp_count;
6489 }
6490 else if (p->signal && edje_program_is_strncmp(p->signal)
6491 && p->source && edje_program_is_strncmp(p->source))
6492 {
6493 array = &edc->programs.strncmp;
6494 count = &edc->programs.strncmp_count;
6495 }
6496 else if (p->signal && edje_program_is_strrncmp(p->signal)
6497 && p->source && edje_program_is_strrncmp(p->source))
6498 {
6499 array = &edc->programs.strrncmp;
6500 count = &edc->programs.strrncmp_count;
6501 }
6502 else
6503 {
6504 array = &edc->programs.fnmatch;
6505 count = &edc->programs.fnmatch_count;
6506 }
6507
6508 temp = *array;
6509 *array = realloc(*array, sizeof (Edje_Program *) * (*count + 1));
6510 if (*array)
6511 {
6512 (*array)[(*count)++] = p;
6513 }
6514 else
6515 {
6516 *array = temp;
6517 }
6518 }
6519
6520 const char *
edje_string_get(const Edje_String * es)6521 edje_string_get(const Edje_String *es)
6522 {
6523 /* FIXME: Handle localization here */
6524 if (!es) return NULL;
6525 return es->str;
6526 }
6527
6528 const char *
edje_string_id_get(const Edje_String * es)6529 edje_string_id_get(const Edje_String *es)
6530 {
6531 /* FIXME: Handle localization here */
6532 if (!es) return NULL;
6533 return es->str;
6534 }
6535
6536 static void
_cb_subobj_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)6537 _cb_subobj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6538 {
6539 Edje *ed = data;
6540 _edje_subobj_unregister(ed, obj);
6541 }
6542
6543 void
_edje_subobj_register(Edje * ed,Evas_Object * ob)6544 _edje_subobj_register(Edje *ed, Evas_Object *ob)
6545 {
6546 ed->subobjs = eina_list_append(ed->subobjs, ob);
6547 evas_object_event_callback_add(ob, EVAS_CALLBACK_DEL,
6548 _cb_subobj_del, ed);
6549 }
6550
6551 void
_edje_subobj_unregister(Edje * ed,Evas_Object * obj)6552 _edje_subobj_unregister(Edje *ed, Evas_Object *obj)
6553 {
6554 ed->subobjs = eina_list_remove(ed->subobjs, obj);
6555 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
6556 _cb_subobj_del, ed);
6557 }
6558
6559 EAPI const char *
edje_object_part_object_name_get(const Evas_Object * obj)6560 edje_object_part_object_name_get(const Evas_Object *obj)
6561 {
6562 Edje_Real_Part *rp;
6563
6564 rp = evas_object_data_get(obj, "real_part");
6565 return rp ? rp->part->name : NULL;
6566 }
6567
6568 Eina_Bool
_edje_real_part_mouse_events_get(Edje * ed EINA_UNUSED,Edje_Real_Part * rp)6569 _edje_real_part_mouse_events_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
6570 {
6571 if (!rp) return EINA_FALSE;
6572
6573 return rp->mouse_events;
6574 }
6575
6576 void
_edje_real_part_mouse_events_set(Edje * ed EINA_UNUSED,Edje_Real_Part * rp,Eina_Bool mouse_events)6577 _edje_real_part_mouse_events_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Eina_Bool mouse_events)
6578 {
6579 if (!rp) return;
6580
6581 rp->mouse_events = !!mouse_events;
6582
6583 if (rp->mouse_events)
6584 {
6585 evas_object_pass_events_set(rp->object, 0);
6586 _edje_callbacks_add(rp->object, ed, rp);
6587 }
6588 else
6589 {
6590 evas_object_pass_events_set(rp->object, 1);
6591 _edje_callbacks_del(rp->object, ed);
6592 }
6593 }
6594
6595 Eina_Bool
_edje_real_part_repeat_events_get(Edje * ed EINA_UNUSED,Edje_Real_Part * rp)6596 _edje_real_part_repeat_events_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
6597 {
6598 if (!rp) return EINA_FALSE;
6599
6600 return rp->repeat_events;
6601 }
6602
6603 void
_edje_real_part_repeat_events_set(Edje * ed EINA_UNUSED,Edje_Real_Part * rp,Eina_Bool repeat_events)6604 _edje_real_part_repeat_events_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Eina_Bool repeat_events)
6605 {
6606 if (!rp) return;
6607
6608 rp->repeat_events = !!repeat_events;
6609
6610 if (rp->repeat_events)
6611 evas_object_repeat_events_set(rp->object, 1);
6612 else
6613 evas_object_repeat_events_set(rp->object, 0);
6614 }
6615
6616 void
_edje_real_part_pointer_mode_set(Edje * ed EINA_UNUSED,Edje_Real_Part * rp,Evas_Object_Pointer_Mode mode)6617 _edje_real_part_pointer_mode_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Evas_Object_Pointer_Mode mode)
6618 {
6619 if (!rp) return;
6620
6621 rp->pointer_mode = mode;
6622
6623 evas_object_pointer_mode_set(rp->object, mode);
6624 }
6625
6626 Evas_Event_Flags
_edje_real_part_ignore_flags_get(Edje * ed EINA_UNUSED,Edje_Real_Part * rp)6627 _edje_real_part_ignore_flags_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
6628 {
6629 if (!rp) return EVAS_EVENT_FLAG_NONE;
6630
6631 return rp->ignore_flags;
6632 }
6633
6634 void
_edje_real_part_ignore_flags_set(Edje * ed EINA_UNUSED,Edje_Real_Part * rp,Evas_Event_Flags ignore_flags)6635 _edje_real_part_ignore_flags_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Evas_Event_Flags ignore_flags)
6636 {
6637 if (!rp) return;
6638
6639 rp->ignore_flags = ignore_flags;
6640 }
6641
6642 Evas_Event_Flags
_edje_real_part_mask_flags_get(Edje * ed EINA_UNUSED,Edje_Real_Part * rp)6643 _edje_real_part_mask_flags_get(Edje *ed EINA_UNUSED, Edje_Real_Part *rp)
6644 {
6645 if (!rp) return EVAS_EVENT_FLAG_NONE;
6646
6647 return rp->mask_flags;
6648 }
6649
6650 void
_edje_real_part_mask_flags_set(Edje * ed EINA_UNUSED,Edje_Real_Part * rp,Evas_Event_Flags mask_flags)6651 _edje_real_part_mask_flags_set(Edje *ed EINA_UNUSED, Edje_Real_Part *rp, Evas_Event_Flags mask_flags)
6652 {
6653 if (!rp) return;
6654
6655 rp->mask_flags = mask_flags;
6656 }
6657
6658 /* Legacy APIs */
6659
6660 static inline Eina_Bool
_edje_part_fetch(const Edje_Object * obj,const char * part,Edje ** ped,Edje_Real_Part ** prp)6661 _edje_part_fetch(const Edje_Object *obj, const char *part, Edje **ped, Edje_Real_Part **prp)
6662 {
6663 if (!part) return EINA_FALSE;
6664
6665 *ped = _edje_fetch(obj);
6666 if (!*ped) return EINA_FALSE;
6667
6668 *prp = _edje_real_part_recursive_get(ped, part);
6669 if (!*prp) return EINA_FALSE;
6670
6671 return EINA_TRUE;
6672 }
6673
6674 EAPI Eina_Bool
edje_object_part_swallow(Edje_Object * obj,const char * part,Evas_Object * obj_swallow)6675 edje_object_part_swallow(Edje_Object *obj, const char *part, Evas_Object *obj_swallow)
6676 {
6677 Edje_Real_Part *rp;
6678 Edje *ed;
6679
6680 if (!_edje_part_fetch(obj, part, &ed, &rp)) return EINA_FALSE;
6681
6682 if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
6683 {
6684 ERR("Invalid call on a non-swallow part: '%s' in group '%s'", part, ed->group);
6685 return EINA_FALSE;
6686 }
6687
6688 return efl_content_set(efl_part(obj, part), obj_swallow);
6689 }
6690
6691 EAPI void
edje_object_part_unswallow(Edje_Object * obj,Evas_Object * obj_swallow)6692 edje_object_part_unswallow(Edje_Object *obj, Evas_Object *obj_swallow)
6693 {
6694 efl_canvas_layout_content_remove(obj, obj_swallow);
6695 }
6696
6697 EAPI Evas_Object *
edje_object_part_swallow_get(const Edje_Object * obj,const char * part)6698 edje_object_part_swallow_get(const Edje_Object *obj, const char *part)
6699 {
6700 Edje_Real_Part *rp;
6701 Edje *ed;
6702
6703 if (!_edje_part_fetch(obj, part, &ed, &rp)) return NULL;
6704
6705 if (rp->part->type != EDJE_PART_TYPE_SWALLOW)
6706 {
6707 // Legacy compatibility: return swallowed_object on non-swallow parts
6708 if ((rp->type == EDJE_RP_TYPE_SWALLOW) && rp->typedata.swallow)
6709 {
6710 INF("Part is not a swallow: '%s' in group '%s'", part, ed->group);
6711 return rp->typedata.swallow->swallowed_object;
6712 }
6713
6714 ERR("Invalid call on a non-swallow part: '%s' in group '%s'", part, ed->group);
6715 return NULL;
6716 }
6717
6718 return efl_content_get(efl_part(obj, part));
6719 }
6720
6721 EAPI Eina_Bool
edje_object_part_text_set(const Edje_Object * obj,const char * part,const char * text)6722 edje_object_part_text_set(const Edje_Object *obj, const char *part, const char *text)
6723 {
6724 Edje *ed;
6725
6726 ed = _edje_fetch(obj);
6727
6728 return _edje_efl_text_text_set((Eo *) obj, ed, part, text, EINA_TRUE, EINA_TRUE);
6729 }
6730
6731 EAPI const char *
edje_object_part_text_get(const Edje_Object * obj,const char * part)6732 edje_object_part_text_get(const Edje_Object *obj, const char *part)
6733 {
6734 Edje_Real_Part *rp;
6735 Edje *ed;
6736
6737 if (!_edje_part_fetch(obj, part, &ed, &rp)) return NULL;
6738
6739 if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
6740 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
6741 {
6742 ERR("Invalid call on a non-text or non-textblock part: '%s' in group '%s'", part, ed->group);
6743 return NULL;
6744 }
6745
6746 ed = _edje_fetch(obj);
6747 if (!ed)
6748 {
6749 ERR("Failed to get Edje data from object: '%p'", obj);
6750 return NULL;
6751 }
6752
6753 return _edje_efl_text_text_get(obj, ed, part, EINA_TRUE, EINA_FALSE);
6754 }
6755
6756 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
6757