1 #include "edje_private.h"
3 static void _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop);
4 static void _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param);
5 static void _edje_param_set(Edje_Real_Part *part, const char *param, const char *value);
7 int _edje_anim_count = 0;
8 Ecore_Animator *_edje_timer = NULL;
9 Eina_List *_edje_animators = NULL;
12 /*============================================================================*
14 *============================================================================*/
17 edje_frametime_set(double t)
19 ecore_animator_frametime_set(t);
23 edje_frametime_get(void)
25 return ecore_animator_frametime_get();
29 edje_object_propagate_callback_add(Evas_Object *obj, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
32 Edje_Signal_Callback *escb;
34 ed = _edje_fetch(obj);
36 if (ed->delete_me) return;
37 escb = calloc(1, sizeof(Edje_Signal_Callback));
38 escb->propagate = EINA_TRUE;
39 escb->signal = eina_stringshare_add("*");
40 escb->source = eina_stringshare_add("*");
43 ed->callbacks = eina_list_append(ed->callbacks, escb);
44 if (ed->walking_callbacks)
47 ed->just_added_callbacks = 1;
50 _edje_callbacks_patterns_clean(ed);
54 edje_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
57 Edje_Signal_Callback *escb;
59 if ((!emission) || (!source) || (!func)) return;
60 ed = _edje_fetch(obj);
62 if (ed->delete_me) return;
63 escb = calloc(1, sizeof(Edje_Signal_Callback));
65 escb->signal = eina_stringshare_add(emission);
67 escb->source = eina_stringshare_add(source);
70 ed->callbacks = eina_list_append(ed->callbacks, escb);
71 if (ed->walking_callbacks)
74 ed->just_added_callbacks = 1;
77 _edje_callbacks_patterns_clean(ed);
81 edje_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source))
85 Edje_Signal_Callback *escb;
87 if ((!emission) || (!source) || (!func)) return NULL;
88 ed = _edje_fetch(obj);
90 if (ed->delete_me) return NULL;
91 EINA_LIST_FOREACH(ed->callbacks, l, escb)
93 if ((escb->func == func) &&
94 ((!escb->signal && !emission[0]) ||
95 (escb->signal && !strcmp(escb->signal, emission))) &&
96 ((!escb->source && !source[0]) ||
97 (escb->source && !strcmp(escb->source, source))))
102 if (ed->walking_callbacks)
105 ed->delete_callbacks = 1;
109 _edje_callbacks_patterns_clean(ed);
111 ed->callbacks = eina_list_remove_list(ed->callbacks, l);
112 if (escb->signal) eina_stringshare_del(escb->signal);
113 if (escb->source) eina_stringshare_del(escb->source);
123 edje_object_signal_callback_del_full(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
127 Edje_Signal_Callback *escb;
129 if ((!emission) || (!source) || (!func)) return NULL;
130 ed = _edje_fetch(obj);
131 if (!ed) return NULL;
132 if (ed->delete_me) return NULL;
133 EINA_LIST_FOREACH(ed->callbacks, l, escb)
135 if ((escb->func == func) && (escb->data == data) &&
136 ((!escb->signal && !emission[0]) ||
137 (escb->signal && !strcmp(escb->signal, emission))) &&
138 ((!escb->source && !source[0]) ||
139 (escb->source && !strcmp(escb->source, source))))
144 if (ed->walking_callbacks)
147 ed->delete_callbacks = 1;
151 _edje_callbacks_patterns_clean(ed);
153 ed->callbacks = eina_list_remove_list(ed->callbacks, l);
154 if (escb->signal) eina_stringshare_del(escb->signal);
155 if (escb->source) eina_stringshare_del(escb->source);
165 edje_object_signal_emit(Evas_Object *obj, const char *emission, const char *source)
169 if ((!emission) || (!source)) return;
170 ed = _edje_fetch(obj);
172 if (ed->delete_me) return;
173 _edje_emit(ed, (char *)emission, (char *)source);
176 /* FIXDOC: Verify/Expand */
178 edje_object_play_set(Evas_Object *obj, Eina_Bool play)
183 Edje_Running_Program *runp;
186 ed = _edje_fetch(obj);
188 if (ed->delete_me) return;
191 if (!ed->paused) return;
193 t = ecore_time_get() - ed->paused_at;
194 EINA_LIST_FOREACH(ed->actions, l, runp)
195 runp->start_time += t;
199 if (ed->paused) return;
200 ed->paused = EINA_TRUE;
201 ed->paused_at = ecore_time_get();
204 for (i = 0; i < ed->table_parts_size; i++)
207 rp = ed->table_parts[i];
208 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
209 edje_object_play_set(rp->swallowed_object, play);
214 edje_object_play_get(const Evas_Object *obj)
218 ed = _edje_fetch(obj);
219 if (!ed) return EINA_FALSE;
220 if (ed->delete_me) return EINA_FALSE;
221 if (ed->paused) return EINA_FALSE;
225 /* FIXDOC: Verify/Expand */
227 edje_object_animation_set(Evas_Object *obj, Eina_Bool on)
233 ed = _edje_fetch(obj);
235 if (ed->delete_me) return;
241 Eina_List *newl = NULL;
244 EINA_LIST_FOREACH(ed->actions, l, data)
245 newl = eina_list_append(newl, data);
248 Edje_Running_Program *runp;
250 runp = eina_list_data_get(newl);
251 newl = eina_list_remove(newl, eina_list_data_get(newl));
252 _edje_program_run_iterate(runp, runp->start_time + TO_DOUBLE(runp->program->tween.time));
253 if (_edje_block_break(ed))
255 eina_list_free(newl);
262 _edje_emit(ed, "load", NULL);
263 if (evas_object_visible_get(obj))
265 evas_object_hide(obj);
266 evas_object_show(obj);
271 for (i = 0; i < ed->table_parts_size; i++)
274 rp = ed->table_parts[i];
275 if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object)
276 edje_object_animation_set(rp->swallowed_object, on);
285 edje_object_animation_get(const Evas_Object *obj)
289 ed = _edje_fetch(obj);
290 if (!ed) return EINA_FALSE;
291 if (ed->delete_me) return EINA_FALSE;
292 if (ed->no_anim) return EINA_FALSE;
296 /* Private Routines */
299 _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
304 Edje_Program_Target *pt;
308 if (ed->delete_me) return EINA_FALSE;
312 t = FROM_DOUBLE(tim - runp->start_time);
313 total = runp->program->tween.time;
315 if (t > FROM_INT(1)) t = FROM_INT(1);
316 EINA_LIST_FOREACH(runp->program->targets, l, pt)
320 rp = ed->table_parts[pt->id % ed->table_parts_size];
321 if (rp) _edje_part_pos_set(ed, rp,
322 runp->program->tween.mode, t,
323 runp->program->tween.v1,
324 runp->program->tween.v2);
327 if (t >= FROM_INT(1))
329 Edje_Program_After *pa;
331 EINA_LIST_FOREACH(runp->program->targets, l, pt)
335 rp = ed->table_parts[pt->id % ed->table_parts_size];
338 _edje_part_description_apply(ed, rp,
339 runp->program->state,
340 runp->program->value,
343 _edje_part_pos_set(ed, rp,
344 runp->program->tween.mode, ZERO,
345 runp->program->tween.v1,
346 runp->program->tween.v2);
353 if (!ed->walking_actions)
356 ed->actions = eina_list_remove(ed->actions, runp);
358 _edje_animators = eina_list_remove(_edje_animators, ed);
360 // _edje_emit(ed, "program,stop", runp->program->name);
361 if (_edje_block_break(ed))
363 if (!ed->walking_actions) free(runp);
366 EINA_LIST_FOREACH(runp->program->after, l, pa)
372 pr = ed->table_programs[pa->id % ed->table_programs_size];
373 if (pr) _edje_program_run(ed, pr, 0, "", "");
374 if (_edje_block_break(ed))
376 if (!ed->walking_actions) free(runp);
383 if (!ed->walking_actions) free(runp);
396 _edje_program_end(Edje *ed, Edje_Running_Program *runp)
399 Edje_Program_Target *pt;
400 // const char *pname = NULL;
403 if (ed->delete_me) return;
406 EINA_LIST_FOREACH(runp->program->targets, l, pt)
412 rp = ed->table_parts[pt->id % ed->table_parts_size];
415 _edje_part_description_apply(ed, rp,
416 runp->program->state,
417 runp->program->value,
420 _edje_part_pos_set(ed, rp,
421 runp->program->tween.mode, ZERO,
422 runp->program->tween.v1,
423 runp->program->tween.v2);
430 // pname = runp->program->name;
431 if (!ed->walking_actions)
434 ed->actions = eina_list_remove(ed->actions, runp);
438 _edje_animators = eina_list_remove(_edje_animators, ed);
441 // _edje_emit(ed, "program,stop", pname);
444 if (free_runp) free(runp);
448 _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig, const char *ssrc)
452 Edje_Program_Target *pt;
454 Edje_Program_After *pa;
455 /* limit self-feeding loops in programs to 64 levels */
456 static int recursions = 0;
457 static int recursion_limit = 0;
459 if (ed->delete_me) return;
460 if ((pr->in.from > 0.0) && (pr->in.range >= 0.0) && (!force))
462 Edje_Pending_Program *pp;
465 pp = calloc(1, sizeof(Edje_Pending_Program));
467 if (pr->in.range > 0.0) r = ((double)rand() / RAND_MAX);
468 pp->timer = ecore_timer_add(pr->in.from + (pr->in.range * r),
469 _edje_pending_timer_cb, pp);
477 ed->pending_actions = eina_list_append(ed->pending_actions, pp);
480 if ((recursions >= 64) || (recursion_limit))
482 ERR("Programs recursing up to recursion limit of %i in '%s' with '%s', '%s' from '%s', '%s'. Disabled.",
483 64, pr->name, ssig, ssrc, ed->path, ed->group);
493 case EDJE_ACTION_TYPE_STATE_SET:
494 if ((pr->tween.time > ZERO) && (!ed->no_anim))
496 Edje_Running_Program *runp;
498 runp = calloc(1, sizeof(Edje_Running_Program));
499 EINA_LIST_FOREACH(pr->targets, l, pt)
503 rp = ed->table_parts[pt->id % ed->table_parts_size];
506 if ((rp->object) && (pr->tween.mode & EDJE_TWEEN_MODE_OPT_FROM_CURRENT))
508 Edje_Calc_Params *tmp;
510 tmp = calloc(1, sizeof(Edje_Calc_Params));
511 if (!tmp) goto low_mem_current;
512 _edje_part_recalc(ed, rp, FLAG_XY, tmp);
514 if (rp->current) free(rp->current);
517 rp->current->x -= ed->x;
518 rp->current->y -= ed->y;
519 rp->current->map.center.x -= ed->x;
520 rp->current->map.center.y -= ed->y;
521 rp->current->map.light.x -= ed->x;
522 rp->current->map.light.y -= ed->y;
523 rp->current->map.persp.x -= ed->x;
524 rp->current->map.persp.y -= ed->y;
529 if (rp->current) free(rp->current);
534 _edje_program_end(ed, rp->program);
535 _edje_part_description_apply(ed, rp,
536 rp->param1.description->state.name,
537 rp->param1.description->state.value,
540 _edje_part_pos_set(ed, rp, pr->tween.mode, ZERO,
547 // _edje_emit(ed, "program,start", pr->name);
548 if (_edje_block_break(ed))
550 ed->actions = eina_list_append(ed->actions, runp);
554 _edje_animators = eina_list_append(_edje_animators, ed);
555 ed->actions = eina_list_append(ed->actions, runp);
556 runp->start_time = ecore_loop_time_get();
560 _edje_timer = ecore_animator_add(_edje_timer_cb, NULL);
565 EINA_LIST_FOREACH(pr->targets, l, pt)
569 rp = ed->table_parts[pt->id % ed->table_parts_size];
573 _edje_program_end(ed, rp->program);
574 _edje_part_description_apply(ed, rp,
579 _edje_part_pos_set(ed, rp, pr->tween.mode, ZERO,
585 // _edje_emit(ed, "program,start", pr->name);
586 if (_edje_block_break(ed)) goto break_prog;
587 // _edje_emit(ed, "program,stop", pr->name);
588 if (_edje_block_break(ed)) goto break_prog;
590 EINA_LIST_FOREACH(pr->after, l, pa)
594 pr2 = ed->table_programs[pa->id % ed->table_programs_size];
595 if (pr2) _edje_program_run(ed, pr2, 0, "", "");
596 if (_edje_block_break(ed)) goto break_prog;
602 case EDJE_ACTION_TYPE_ACTION_STOP:
603 // _edje_emit(ed, "program,start", pr->name);
604 EINA_LIST_FOREACH(pr->targets, l, pt)
607 Edje_Running_Program *runp;
608 Edje_Pending_Program *pp;
610 for (ll = ed->actions; ll; )
614 if (pt->id == runp->program->id)
616 _edje_program_end(ed, runp);
620 for (ll = ed->pending_actions; ll; )
624 if (pt->id == pp->program->id)
626 ed->pending_actions = eina_list_remove(ed->pending_actions, pp);
627 ecore_timer_del(pp->timer);
635 // _edje_emit(ed, "program,stop", pr->name);
636 if (_edje_block_break(ed)) goto break_prog;
638 case EDJE_ACTION_TYPE_SIGNAL_EMIT:
639 // _edje_emit(ed, "program,start", pr->name);
640 if (_edje_block_break(ed)) goto break_prog;
641 _edje_emit(ed, pr->state, pr->state2);
642 if (_edje_block_break(ed)) goto break_prog;
643 // _edje_emit(ed, "program,stop", pr->name);
644 if (_edje_block_break(ed)) goto break_prog;
646 case EDJE_ACTION_TYPE_DRAG_VAL_SET:
647 // _edje_emit(ed, "program,start", pr->name);
648 if (_edje_block_break(ed)) goto break_prog;
649 EINA_LIST_FOREACH(pr->targets, l, pt)
653 rp = ed->table_parts[pt->id % ed->table_parts_size];
654 if ((rp) && (rp->drag) && (rp->drag->down.count == 0))
656 rp->drag->val.x = pr->value;
657 rp->drag->val.y = pr->value2;
658 if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0;
659 else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0;
660 if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0;
661 else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0;
662 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
663 _edje_emit(ed, "drag,set", rp->part->name);
664 if (_edje_block_break(ed)) goto break_prog;
668 // _edje_emit(ed, "program,stop", pr->name);
669 if (_edje_block_break(ed)) goto break_prog;
671 case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
672 // _edje_emit(ed, "program,start", pr->name);
673 if (_edje_block_break(ed)) goto break_prog;
674 EINA_LIST_FOREACH(pr->targets, l, pt)
678 rp = ed->table_parts[pt->id % ed->table_parts_size];
679 if ((rp) && (rp->drag) && (rp->drag->down.count == 0))
681 rp->drag->val.x += pr->value * rp->drag->step.x * rp->part->dragable.x;
682 rp->drag->val.y += pr->value2 * rp->drag->step.y * rp->part->dragable.y;
683 if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0;
684 else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0;
685 if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0;
686 else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0;
687 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
688 _edje_emit(ed, "drag,step", rp->part->name);
689 if (_edje_block_break(ed)) goto break_prog;
693 // _edje_emit(ed, "program,stop", pr->name);
694 if (_edje_block_break(ed)) goto break_prog;
696 case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
697 // _edje_emit(ed, "program,start", pr->name);
698 if (_edje_block_break(ed)) goto break_prog;
699 EINA_LIST_FOREACH(pr->targets, l, pt)
703 rp = ed->table_parts[pt->id % ed->table_parts_size];
704 if ((rp) && (rp->drag) && (rp->drag->down.count == 0))
706 rp->drag->val.x += pr->value * rp->drag->page.x * rp->part->dragable.x;
707 rp->drag->val.y += pr->value2 * rp->drag->page.y * rp->part->dragable.y;
708 if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0;
709 else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0;
710 if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0;
711 else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0;
712 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
713 _edje_emit(ed, "drag,page", rp->part->name);
714 if (_edje_block_break(ed)) goto break_prog;
718 // _edje_emit(ed, "program,stop", pr->name);
719 if (_edje_block_break(ed)) goto break_prog;
721 case EDJE_ACTION_TYPE_SCRIPT:
725 // _edje_emit(ed, "program,start", pr->name);
726 if (_edje_block_break(ed)) goto break_prog;
727 snprintf(fname, sizeof(fname), "_p%i", pr->id);
728 _edje_embryo_test_run(ed, fname, ssig, ssrc);
729 // _edje_emit(ed, "program,stop", pr->name);
730 if (_edje_block_break(ed)) goto break_prog;
734 case EDJE_ACTION_TYPE_FOCUS_SET:
736 ed->focused_part = NULL;
739 EINA_LIST_FOREACH(pr->targets, l, pt)
743 rp = ed->table_parts[pt->id % ed->table_parts_size];
746 if (ed->focused_part != rp)
748 if (ed->focused_part)
749 _edje_emit(ed, "focus,part,out",
750 ed->focused_part->part->name);
751 ed->focused_part = rp;
752 _edje_emit(ed, "focus,part,in",
753 ed->focused_part->part->name);
760 case EDJE_ACTION_TYPE_FOCUS_OBJECT:
763 Evas_Object *focused;
765 focused = evas_focus_get(evas_object_evas_get(ed->obj));
770 /* Check if the current swallowed object is one of my child. */
771 for (i = 0; i < ed->table_parts_size; ++i)
773 rp = ed->table_parts[i];
774 if (rp && rp->swallowed_object == focused)
776 evas_object_focus_set(focused, EINA_FALSE);
784 EINA_LIST_FOREACH(pr->targets, l, pt)
788 rp = ed->table_parts[pt->id % ed->table_parts_size];
789 if (rp && rp->swallowed_object)
790 evas_object_focus_set(rp->swallowed_object, EINA_TRUE);
795 case EDJE_ACTION_TYPE_SOUND_SAMPLE:
796 if (_edje_block_break(ed))
798 _edje_multisense_internal_sound_sample_play(ed, pr->sample_name, pr->speed);
800 case EDJE_ACTION_TYPE_SOUND_TONE:
801 if (_edje_block_break(ed))
803 _edje_multisense_internal_sound_tone_play(ed, pr->tone_name, pr->duration);
805 case EDJE_ACTION_TYPE_PARAM_COPY:
807 Edje_Real_Part *src_part, *dst_part;
809 // _edje_emit(ed, "program,start", pr->name);
810 if (_edje_block_break(ed)) goto break_prog;
812 src_part = ed->table_parts[pr->param.src % ed->table_parts_size];
813 dst_part = ed->table_parts[pr->param.dst % ed->table_parts_size];
814 _edje_param_copy(src_part, pr->state, dst_part, pr->state2);
816 if (_edje_block_break(ed)) goto break_prog;
817 // _edje_emit(ed, "program,stop", pr->name);
818 if (_edje_block_break(ed)) goto break_prog;
821 case EDJE_ACTION_TYPE_PARAM_SET:
823 Edje_Real_Part *part;
825 // _edje_emit(ed, "program,start", pr->name);
826 if (_edje_block_break(ed)) goto break_prog;
828 part = ed->table_parts[pr->param.dst % ed->table_parts_size];
829 _edje_param_set(part, pr->state, pr->state2);
831 if (_edje_block_break(ed)) goto break_prog;
832 // _edje_emit(ed, "program,stop", pr->name);
833 if (_edje_block_break(ed)) goto break_prog;
837 // _edje_emit(ed, "program,start", pr->name);
838 // _edje_emit(ed, "program,stop", pr->name);
841 if (!((pr->action == EDJE_ACTION_TYPE_STATE_SET)
842 /* hmm this fucks somethgin up. must look into it later */
843 /* && (pr->tween.time > ZERO) && (!ed->no_anim))) */
846 EINA_LIST_FOREACH(pr->after, l, pa)
850 pr2 = ed->table_programs[pa->id % ed->table_programs_size];
851 if (pr2) _edje_program_run(ed, pr2, 0, "", "");
852 if (_edje_block_break(ed)) goto break_prog;
860 if (recursions == 0) recursion_limit = 0;
865 _edje_emit(Edje *ed, const char *sig, const char *src)
867 _edje_emit_full(ed, sig, src, NULL, NULL);
870 /* data should either be NULL or a malloc allocated data */
872 _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*free_func)(void *))
874 Edje_Message_Signal emsg;
878 if (!ed->collection) return;
879 if (ed->delete_me) return;
880 broadcast = ed->collection->broadcast_signal;
882 sep = strchr(sig, EDJE_PART_PATH_SEPARATOR);
884 /* If we are not sending the signal to a part of the child, the
885 * signal if for ourself
889 Edje_Real_Part *rp = NULL;
896 /* the signal contains a colon, split the signal into "parts:signal" */
897 length = sep - sig + 1;
898 part = alloca(length);
899 memcpy(part, sig, length - 1);
900 part[length - 1] = '\0';
904 /* lookup for alias */
905 if (ed->collection && ed->collection->alias)
909 alias = eina_hash_find(ed->collection->alias, part);
915 alien = strlen(alias);
916 nslen = strlen(newsig);
917 length = alien + nslen + 2;
919 aliased = alloca(length);
920 memcpy(aliased, alias, alien);
921 aliased[alien] = EDJE_PART_PATH_SEPARATOR;
922 memcpy(aliased + alien + 1, newsig, nslen + 1);
924 _edje_emit(ed, aliased, src);
929 /* search for the index if present and remove it from the part */
930 idx = strchr(part, EDJE_PART_PATH_SEPARATOR_INDEXL);
935 end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR);
936 if (end && end != idx + 1)
940 tmp = alloca(end - idx - 1);
941 memcpy(tmp, idx + 1, end - idx - 1);
942 tmp[end - idx - 1] = '\0';
952 /* search for the right part now */
953 rp = _edje_real_part_get(ed, part);
956 switch (rp->part->type)
958 case EDJE_PART_TYPE_GROUP:
959 if (!rp->swallowed_object) goto end;
960 ed2 = _edje_fetch(rp->swallowed_object);
963 _edje_emit(ed2, newsig, src);
964 broadcast = EINA_FALSE;
967 case EDJE_PART_TYPE_EXTERNAL:
968 if (!rp->swallowed_object) break ;
972 _edje_external_signal_emit(rp->swallowed_object, newsig, src);
978 child = _edje_children_get(rp, idx);
979 ed2 = _edje_fetch(child);
981 _edje_emit(ed2, newsig, src);
983 broadcast = EINA_FALSE;
986 case EDJE_PART_TYPE_BOX:
987 case EDJE_PART_TYPE_TABLE:
992 child = _edje_children_get(rp, idx);
993 ed2 = _edje_fetch(child);
995 _edje_emit(ed2, newsig, src);
996 broadcast = EINA_FALSE;
1001 // ERR("SPANK SPANK SPANK !!!\nYou should never be here !");
1011 emsg.data = calloc(1, sizeof(*(emsg.data)));
1013 emsg.data->data = data;
1014 emsg.data->free_func = free_func;
1020 /* new sends code */
1022 edje_object_message_send(ed->obj, EDJE_MESSAGE_SIGNAL, 0, &emsg);
1024 _edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
1025 /* old send code - use api now
1026 _edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
1027 EINA_LIST_FOREACH(ed->subobjs, l, obj)
1031 ed2 = _edje_fetch(obj);
1033 if (ed2->delete_me) continue;
1034 _edje_message_send(ed2, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
1037 if (emsg.data && (--(emsg.data->ref) == 0))
1039 if (emsg.data->free_func)
1041 emsg.data->free_func(emsg.data->data);
1047 struct _Edje_Program_Data
1054 static Eina_Bool _edje_glob_callback(Edje_Program *pr, void *dt)
1056 struct _Edje_Program_Data *data = dt;
1057 Edje_Real_Part *rp = NULL;
1058 Eina_Bool exec = EINA_TRUE;
1060 if (pr->filter.state)
1062 rp = _edje_real_part_get(data->ed, pr->filter.part ? pr->filter.part : data->source);
1064 exec = (rp->chosen_description->state.name == pr->filter.state);
1069 data->matches = eina_list_append(data->matches, pr);
1075 _edje_callbacks_patterns_clean(Edje *ed)
1077 _edje_signals_sources_patterns_clean(&ed->patterns.callbacks);
1079 eina_rbtree_delete(ed->patterns.callbacks.exact_match,
1080 EINA_RBTREE_FREE_CB(edje_match_signal_source_free),
1082 ed->patterns.callbacks.exact_match = NULL;
1084 ed->patterns.callbacks.u.callbacks.globing = eina_list_free(ed->patterns.callbacks.u.callbacks.globing);
1088 _edje_callbacks_patterns_init(Edje *ed)
1090 Edje_Signals_Sources_Patterns *ssp = &ed->patterns.callbacks;
1092 if ((ssp->signals_patterns) || (ssp->sources_patterns) ||
1093 (ssp->u.callbacks.globing) || (ssp->exact_match))
1096 ssp->u.callbacks.globing = edje_match_callback_hash_build(ed->callbacks,
1099 ssp->signals_patterns = edje_match_callback_signal_init(ssp->u.callbacks.globing);
1100 ssp->sources_patterns = edje_match_callback_source_init(ssp->u.callbacks.globing);
1103 /* FIXME: what if we delete the evas object??? */
1105 _edje_emit_handle(Edje *ed, const char *sig, const char *src,
1106 Edje_Message_Signal_Data *sdata, Eina_Bool prop)
1108 if (ed->delete_me) return;
1111 // printf("EDJE EMIT: (%p) signal: \"%s\" source: \"%s\"\n", ed, sig, src);
1116 if (ed->collection && ed->L)
1117 _edje_lua2_script_func_signal(ed, sig, src);
1121 #ifdef EDJE_PROGRAM_CACHE
1122 Edje_Part_Collection *ec;
1128 #ifdef EDJE_PROGRAM_CACHE
1129 ec = ed->collection;
1132 tmps = alloca(l1 + l2 + 3); /* \0, \337, \0 */
1135 strcpy(&(tmps[l1 + 1]), src);
1139 #ifdef EDJE_PROGRAM_CACHE
1145 if (eina_hash_find(ec->prog_cache.no_matches, tmps))
1149 else if ((matches = eina_hash_find(ec->prog_cache.matches, tmps)))
1151 EINA_LIST_FOREACH(matches, l, pr)
1153 Eina_Bool exec = EINA_TRUE;
1155 if (pr->filter.state)
1159 rp = _edje_real_part_get(ed, pr->filter.part ? pr->filter.part : src);
1165 exec = (rp->chosen_description->state.name == pr->filter.state);
1172 EINA_LIST_FOREACH(matches, l, pr)
1175 _edje_program_run(ed, pr, 0, sig, src);
1176 if (_edje_block_break(ed))
1188 struct _Edje_Program_Data data;
1192 data.matches = NULL;
1194 if (ed->table_programs_size > 0)
1196 const Eina_List *match;
1200 if (ed->patterns.programs.u.programs.globing)
1201 if (edje_match_programs_exec(ed->patterns.programs.signals_patterns,
1202 ed->patterns.programs.sources_patterns,
1205 ed->patterns.programs.u.programs.globing,
1206 _edje_glob_callback,
1211 match = edje_match_signal_source_hash_get(sig, src,
1212 ed->patterns.programs.exact_match);
1213 EINA_LIST_FOREACH(match, l, pr)
1214 _edje_glob_callback(pr, &data);
1216 #ifdef EDJE_PROGRAM_CACHE
1217 EINA_LIST_FOREACH(data.matches, l, pr)
1219 EINA_LIST_FREE(data.matches, pr)
1223 _edje_program_run(ed, pr, 0, sig, src);
1225 if (_edje_block_break(ed))
1227 eina_list_free(data.matches);
1228 data.matches = NULL;
1234 #ifdef EDJE_PROGRAM_CACHE
1237 if (data.matches == NULL)
1239 if (!ec->prog_cache.no_matches)
1240 ec->prog_cache.no_matches = eina_hash_string_superfast_new(NULL);
1241 eina_hash_add(ec->prog_cache.no_matches, tmps, ed);
1245 if (!ec->prog_cache.matches)
1246 ec->prog_cache.matches = eina_hash_string_superfast_new(NULL);
1247 eina_hash_add(ec->prog_cache.matches, tmps, data.matches);
1252 _edje_emit_cb(ed, sig, src, sdata, prop);
1253 if (_edje_block_break(ed))
1264 /* Extra data for callbacks */
1265 static void *callback_extra_data = NULL;
1268 edje_object_signal_callback_extra_data_get(void)
1270 return callback_extra_data;
1273 /* FIXME: what if we delete the evas object??? */
1275 _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop)
1279 if (ed->delete_me) return;
1284 if (ed->just_added_callbacks)
1285 _edje_callbacks_patterns_clean(ed);
1287 ed->walking_callbacks++;
1291 Edje_Signal_Callback *escb;
1292 const Eina_List *match;
1293 const Eina_List *l2;
1295 callback_extra_data = (data) ? data->data : NULL;
1297 _edje_callbacks_patterns_init(ed);
1298 if (ed->patterns.callbacks.u.callbacks.globing)
1299 r = edje_match_callback_exec(ed->patterns.callbacks.signals_patterns,
1300 ed->patterns.callbacks.sources_patterns,
1303 ed->patterns.callbacks.u.callbacks.globing,
1310 match = edje_match_signal_source_hash_get(sig, src,
1311 ed->patterns.callbacks.exact_match);
1312 EINA_LIST_FOREACH(match, l2, escb)
1314 if ((prop) && (escb->propagate)) continue;
1315 if ((!escb->just_added) && (!escb->delete_me))
1317 escb->func(escb->data, ed->obj, sig, src);
1318 if (_edje_block_break(ed))
1325 ed->walking_callbacks--;
1326 if (!ed->walking_callbacks &&
1327 ((ed->delete_callbacks) || (ed->just_added_callbacks)))
1329 ed->delete_callbacks = 0;
1330 ed->just_added_callbacks = 0;
1334 Edje_Signal_Callback *escb = l->data;
1335 Eina_List *next_l = l->next;
1337 if (escb->just_added)
1338 escb->just_added = 0;
1339 if (escb->delete_me)
1341 ed->callbacks = eina_list_remove_list(ed->callbacks, l);
1342 if (escb->signal) eina_stringshare_del(escb->signal);
1343 if (escb->source) eina_stringshare_del(escb->source);
1349 _edje_callbacks_patterns_clean(ed);
1356 static const Edje_External_Param_Info *
1357 _edje_external_param_info_get(const Evas_Object *obj, const char *name)
1359 const Edje_External_Type *type;
1360 const Edje_External_Param_Info *info;
1362 type = evas_object_data_get(obj, "Edje_External_Type");
1363 if (!type) return NULL;
1364 for (info = type->parameters_info; info->name; info++)
1365 if (!strcmp(info->name, name)) return info;
1370 static Edje_External_Param *
1371 _edje_param_external_get(Edje_Real_Part *rp, const char *name, Edje_External_Param *param)
1373 Evas_Object *swallowed_object = rp->swallowed_object;
1374 const Edje_External_Param_Info *info;
1376 info = _edje_external_param_info_get(swallowed_object, name);
1377 if (!info) return NULL;
1379 memset(param, 0, sizeof(*param));
1380 param->name = info->name;
1381 param->type = info->type;
1382 if (!_edje_external_param_get(NULL, rp, param)) return NULL;
1386 /* simulate external properties for native objects */
1387 static Edje_External_Param *
1388 _edje_param_native_get(Edje_Real_Part *rp, const char *name, Edje_External_Param *param, void **free_ptr)
1391 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
1392 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
1394 if (!strcmp(name, "text"))
1397 param->type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
1399 _edje_recalc_do(rp->edje);
1400 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1401 param->s = _edje_entry_text_get(rp);
1402 else if (rp->part->type == EDJE_PART_TYPE_TEXT)
1403 param->s = rp->text.text;
1405 param->s = evas_object_textblock_text_markup_get(rp->object);
1408 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1410 if (!strcmp(name, "text_unescaped"))
1413 param->type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
1415 _edje_recalc_do(rp->edje);
1416 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1418 const char *tmp = _edje_entry_text_get(rp);
1419 char *unescaped = _edje_text_unescape(tmp);
1420 *free_ptr = unescaped;
1421 param->s = unescaped;
1423 else if (rp->part->type == EDJE_PART_TYPE_TEXT)
1424 param->s = rp->text.text;
1430 tmp = evas_object_textblock_text_markup_get(rp->object);
1431 unescaped = _edje_text_unescape(tmp);
1432 *free_ptr = unescaped;
1433 param->s = unescaped;
1439 if ((rp->entry_data) &&
1440 (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) &&
1441 (!strcmp(name, "select_allow")))
1444 param->type = EDJE_EXTERNAL_PARAM_TYPE_BOOL;
1445 param->i = _edje_entry_select_allow_get(rp);
1451 if ((rp->drag) && (rp->drag->down.count == 0))
1453 if (!strncmp(name, "drag_", sizeof("drag_") - 1))
1455 const char *sub_name = name + sizeof("drag_") - 1;
1456 if (!strcmp(sub_name, "value_x"))
1460 _edje_recalc_do(rp->edje);
1461 d = TO_DOUBLE(rp->drag->val.x);
1462 if (rp->part->dragable.x < 0) d = 1.0 - d;
1464 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1468 if (!strcmp(sub_name, "value_y"))
1472 _edje_recalc_do(rp->edje);
1473 d = TO_DOUBLE(rp->drag->val.y);
1474 if (rp->part->dragable.y < 0) d = 1.0 - d;
1476 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1481 if (!strcmp(sub_name, "size_w"))
1483 _edje_recalc_do(rp->edje);
1485 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1486 param->d = TO_DOUBLE(rp->drag->size.x);
1489 if (!strcmp(sub_name, "size_h"))
1491 _edje_recalc_do(rp->edje);
1493 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1494 param->d = TO_DOUBLE(rp->drag->size.y);
1498 if (!strcmp(sub_name, "step_x"))
1500 _edje_recalc_do(rp->edje);
1502 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1503 param->d = TO_DOUBLE(rp->drag->step.x);
1506 if (!strcmp(sub_name, "step_y"))
1508 _edje_recalc_do(rp->edje);
1510 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1511 param->d = TO_DOUBLE(rp->drag->step.y);
1515 if (!strcmp(sub_name, "page_x"))
1517 _edje_recalc_do(rp->edje);
1519 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1520 param->d = TO_DOUBLE(rp->drag->page.x);
1523 if (!strcmp(sub_name, "page_y"))
1525 _edje_recalc_do(rp->edje);
1527 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1528 param->d = TO_DOUBLE(rp->drag->page.y);
1540 _edje_param_native_set(Edje_Real_Part *rp, const char *name, const Edje_External_Param *param)
1542 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
1543 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
1545 if (!strcmp(name, "text"))
1547 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_STRING)
1550 _edje_object_part_text_raw_set
1551 (rp->edje->obj, rp, rp->part->name, param->s);
1554 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1556 if (!strcmp(name, "text_unescaped"))
1558 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_STRING)
1561 if (rp->part->type == EDJE_PART_TYPE_TEXT)
1562 _edje_object_part_text_raw_set
1563 (rp->edje->obj, rp, rp->part->name, param->s);
1566 char *escaped = _edje_text_escape(param->s);
1567 _edje_object_part_text_raw_set
1568 (rp->edje->obj, rp, rp->part->name, escaped);
1575 if ((rp->entry_data) &&
1576 (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) &&
1577 (!strcmp(name, "select_allow")))
1579 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_BOOL)
1581 _edje_entry_select_allow_set(rp, param->i);
1587 if ((rp->drag) && (rp->drag->down.count == 0))
1589 if (!strncmp(name, "drag_", sizeof("drag_") - 1))
1591 const char *sub_name = name + sizeof("drag_") - 1;
1592 if (!strcmp(sub_name, "value_x"))
1595 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1598 if (rp->part->dragable.confine_id != -1)
1599 d = CLAMP(d, 0.0, 1.0);
1600 if (rp->part->dragable.x < 0) d = 1.0 - d;
1601 if (rp->drag->val.x == FROM_DOUBLE(d)) return EINA_TRUE;
1602 rp->drag->val.x = FROM_DOUBLE(d);
1603 #ifdef EDJE_CALC_CACHE
1606 _edje_dragable_pos_set
1607 (rp->edje, rp, rp->drag->val.x, rp->drag->val.y);
1608 _edje_emit(rp->edje, "drag,set", rp->part->name);
1611 if (!strcmp(sub_name, "value_y"))
1614 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1617 if (rp->part->dragable.confine_id != -1)
1618 d = CLAMP(d, 0.0, 1.0);
1619 if (rp->part->dragable.y < 0) d = 1.0 - d;
1620 if (rp->drag->val.y == FROM_DOUBLE(d)) return EINA_TRUE;
1621 rp->drag->val.y = FROM_DOUBLE(d);
1622 #ifdef EDJE_CALC_CACHE
1625 _edje_dragable_pos_set
1626 (rp->edje, rp, rp->drag->val.x, rp->drag->val.y);
1627 _edje_emit(rp->edje, "drag,set", rp->part->name);
1631 if (!strcmp(sub_name, "size_w"))
1633 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1635 rp->drag->size.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1636 rp->edje->recalc_call = 1;
1637 rp->edje->dirty = 1;
1638 #ifdef EDJE_CALC_CACHE
1641 _edje_recalc(rp->edje);
1644 if (!strcmp(sub_name, "size_h"))
1646 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1648 rp->drag->size.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1649 rp->edje->recalc_call = 1;
1650 rp->edje->dirty = 1;
1651 #ifdef EDJE_CALC_CACHE
1654 _edje_recalc(rp->edje);
1658 if (!strcmp(sub_name, "step_x"))
1660 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1662 rp->drag->step.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1663 #ifdef EDJE_CALC_CACHE
1668 if (!strcmp(sub_name, "step_y"))
1670 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1672 rp->drag->step.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1673 #ifdef EDJE_CALC_CACHE
1679 if (!strcmp(sub_name, "page_x"))
1681 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1683 rp->drag->page.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1684 #ifdef EDJE_CALC_CACHE
1689 if (!strcmp(sub_name, "page_y"))
1691 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1693 rp->drag->page.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1694 #ifdef EDJE_CALC_CACHE
1707 static const Edje_External_Param_Info *
1708 _edje_native_param_info_get(const Edje_Real_Part *rp, const char *name)
1710 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
1711 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
1713 if (!strcmp(name, "text"))
1715 static const Edje_External_Param_Info pi =
1716 EDJE_EXTERNAL_PARAM_INFO_STRING("text");
1719 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1721 if (!strcmp(name, "text_unescaped"))
1723 static const Edje_External_Param_Info pi =
1724 EDJE_EXTERNAL_PARAM_INFO_STRING("text_unescaped");
1727 if (!strcmp(name, "select_allow"))
1729 static const Edje_External_Param_Info pi =
1730 EDJE_EXTERNAL_PARAM_INFO_BOOL("text_unescaped");
1736 if ((rp->drag) && (rp->drag->down.count == 0))
1738 if (!strncmp(name, "drag_", sizeof("drag_") - 1))
1740 name += sizeof("drag_") - 1;
1741 if (!strcmp(name, "value_x"))
1743 static const Edje_External_Param_Info pi =
1744 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_x");
1747 if (!strcmp(name, "value_y"))
1749 static const Edje_External_Param_Info pi =
1750 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_y");
1753 if (!strcmp(name, "size_w"))
1755 static const Edje_External_Param_Info pi =
1756 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_w");
1759 if (!strcmp(name, "size_h"))
1761 static const Edje_External_Param_Info pi =
1762 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_h");
1765 if (!strcmp(name, "step_x"))
1767 static const Edje_External_Param_Info pi =
1768 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_x");
1771 if (!strcmp(name, "step_y"))
1773 static const Edje_External_Param_Info pi =
1774 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_y");
1777 if (!strcmp(name, "page_x"))
1779 static const Edje_External_Param_Info pi =
1780 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_x");
1783 if (!strcmp(name, "page_y"))
1785 static const Edje_External_Param_Info pi =
1786 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_y");
1797 static Edje_External_Param *
1798 _edje_param_convert(Edje_External_Param *param, const Edje_External_Param_Info *dst_info)
1800 if (param->type == dst_info->type) return param;
1802 switch (dst_info->type)
1804 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1805 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1808 switch (param->type)
1810 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1813 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1814 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1815 i = (param->s) ? atoi(param->s) : 0;
1817 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1818 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1824 if (dst_info->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
1826 param->type = dst_info->type;
1831 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1834 switch (param->type)
1836 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1837 d = (double)param->i;
1839 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1840 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1841 d = (param->s) ? atof(param->s) : 0.0;
1843 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1844 d = (double)param->i;
1849 param->type = dst_info->type;
1854 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1857 switch (param->type)
1859 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1860 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1861 if (!snprintf(s, sizeof(s), "%i", param->i)) return NULL;
1863 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1864 if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL;
1866 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1867 param->type = dst_info->type;
1872 param->type = dst_info->type;
1877 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1881 switch (param->type)
1883 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1884 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1885 if (!snprintf(s, sizeof(s), "%i", param->i)) return NULL;
1888 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1889 if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL;
1892 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1899 param->type = dst_info->type;
1900 if (param->s != val) param->s = val;
1904 default: return NULL;
1909 _edje_param_validate(const Edje_External_Param *param, const Edje_External_Param_Info *info)
1913 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1914 return ((param->i == 0) || (param->i == 1));
1916 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1917 if ((info->info.i.min != EDJE_EXTERNAL_INT_UNSET) &&
1918 (info->info.i.min > param->i))
1921 if ((info->info.i.max != EDJE_EXTERNAL_INT_UNSET) &&
1922 (info->info.i.max < param->i))
1927 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1928 if ((info->info.d.min != EDJE_EXTERNAL_DOUBLE_UNSET) &&
1929 (info->info.d.min > param->d))
1932 if ((info->info.d.max != EDJE_EXTERNAL_DOUBLE_UNSET) &&
1933 (info->info.d.max < param->d))
1938 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1939 if (!param->s) return EINA_FALSE;
1940 if (info->info.s.accept_fmt)
1941 INF("string 'accept_fmt' validation not implemented.");
1942 if (info->info.s.deny_fmt)
1943 INF("string 'deny_fmt' validation not implemented.");
1946 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1948 const char **itr = info->info.c.choices;
1949 if (!itr) return EINA_FALSE;
1951 if (!strcmp(*itr, param->s))
1956 default: return EINA_FALSE;
1961 _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param)
1963 Edje_External_Param val;
1964 const Edje_External_Param_Info *dst_info;
1965 void *free_ptr = NULL;
1967 if ((!src_part) || (!src_param) || (!dst_part) || (!dst_param))
1970 if (dst_part->part->type == EDJE_PART_TYPE_EXTERNAL)
1971 dst_info = _edje_external_param_info_get
1972 (dst_part->swallowed_object, dst_param);
1974 dst_info = _edje_native_param_info_get(dst_part, dst_param);
1978 ERR("cannot copy, invalid destination parameter '%s' of part '%s'",
1979 dst_param, dst_part->part->name);
1983 if (src_part->part->type == EDJE_PART_TYPE_EXTERNAL)
1985 if (!_edje_param_external_get
1986 (src_part, src_param, &val))
1988 ERR("cannot get parameter '%s' of part '%s'",
1989 src_param, src_part->part->name);
1995 if (!_edje_param_native_get(src_part, src_param, &val, &free_ptr))
1997 ERR("cannot get parameter '%s' of part '%s'",
1998 src_param, src_part->part->name);
2003 if (!_edje_param_convert(&val, dst_info))
2005 ERR("cannot convert parameter type %s to requested type %s",
2006 edje_external_param_type_str(val.type),
2007 edje_external_param_type_str(dst_info->type));
2011 if (!_edje_param_validate(&val, dst_info))
2013 ERR("incorrect parameter value failed validation for type %s",
2014 edje_external_param_type_str(dst_info->type));
2018 if (dst_part->part->type == EDJE_PART_TYPE_EXTERNAL)
2020 val.name = dst_param;
2021 if (!_edje_external_param_set(NULL, dst_part, &val))
2023 ERR("failed to set parameter '%s' (%s) of part '%s'",
2024 dst_param, edje_external_param_type_str(dst_info->type),
2025 dst_part->part->name);
2031 if (!_edje_param_native_set(dst_part, dst_param, &val))
2033 ERR("failed to set parameter '%s' (%s) of part '%s'",
2034 dst_param, edje_external_param_type_str(dst_info->type),
2035 dst_part->part->name);
2045 _edje_param_set(Edje_Real_Part *part, const char *param, const char *value)
2047 Edje_External_Param val;
2048 const Edje_External_Param_Info *info;
2050 if ((!part) || (!param) || (!value))
2053 if (part->part->type == EDJE_PART_TYPE_EXTERNAL)
2054 info = _edje_external_param_info_get(part->swallowed_object, param);
2056 info = _edje_native_param_info_get(part, param);
2060 ERR("cannot copy, invalid destination parameter '%s' of part '%s'",
2061 param, part->part->name);
2065 val.name = "(temp)";
2066 val.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2069 if (!_edje_param_convert(&val, info))
2071 ERR("cannot convert parameter type STRING to requested type %s",
2072 edje_external_param_type_str(info->type));
2076 if (!_edje_param_validate(&val, info))
2078 ERR("incorrect parameter value failed validation for type %s",
2079 edje_external_param_type_str(info->type));
2083 if (part->part->type == EDJE_PART_TYPE_EXTERNAL)
2086 if (!_edje_external_param_set(NULL, part, &val))
2088 ERR("failed to set parameter '%s' (%s) of part '%s'",
2089 param, edje_external_param_type_str(info->type),
2096 if (!_edje_param_native_set(part, param, &val))
2098 ERR("failed to set parameter '%s' (%s) of part '%s'",
2099 param, edje_external_param_type_str(info->type),