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 = EINA_TRUE;
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 = EINA_TRUE;
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)
104 escb->delete_me = EINA_TRUE;
105 ed->delete_callbacks = EINA_TRUE;
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)
146 escb->delete_me = EINA_TRUE;
147 ed->delete_callbacks = EINA_TRUE;
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;
192 ed->paused = EINA_FALSE;
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) &&
209 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
210 (rp->typedata.swallow)) &&
211 (rp->typedata.swallow->swallowed_object))
212 edje_object_play_set(rp->typedata.swallow->swallowed_object, play);
217 edje_object_play_get(const Evas_Object *obj)
221 ed = _edje_fetch(obj);
222 if (!ed) return EINA_FALSE;
223 if (ed->delete_me) return EINA_FALSE;
224 if (ed->paused) return EINA_FALSE;
228 /* FIXDOC: Verify/Expand */
230 edje_object_animation_set(Evas_Object *obj, Eina_Bool on)
236 ed = _edje_fetch(obj);
238 if (ed->delete_me) return;
244 Eina_List *newl = NULL;
247 EINA_LIST_FOREACH(ed->actions, l, data)
248 newl = eina_list_append(newl, data);
251 Edje_Running_Program *runp;
253 runp = eina_list_data_get(newl);
254 newl = eina_list_remove(newl, eina_list_data_get(newl));
255 _edje_program_run_iterate(runp, runp->start_time + TO_DOUBLE(runp->program->tween.time));
256 if (_edje_block_break(ed))
258 eina_list_free(newl);
265 _edje_emit(ed, "load", NULL);
266 if (evas_object_visible_get(obj))
268 evas_object_hide(obj);
269 evas_object_show(obj);
274 for (i = 0; i < ed->table_parts_size; i++)
277 rp = ed->table_parts[i];
278 if ((rp->part->type == EDJE_PART_TYPE_GROUP) &&
279 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
280 (rp->typedata.swallow)) &&
281 (rp->typedata.swallow->swallowed_object))
282 edje_object_animation_set(rp->typedata.swallow->swallowed_object, on);
291 edje_object_animation_get(const Evas_Object *obj)
295 ed = _edje_fetch(obj);
296 if (!ed) return EINA_FALSE;
297 if (ed->delete_me) return EINA_FALSE;
298 if (ed->no_anim) return EINA_FALSE;
302 /* Private Routines */
305 _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
310 Edje_Program_Target *pt;
314 if (ed->delete_me) return EINA_FALSE;
318 t = FROM_DOUBLE(tim - runp->start_time);
319 total = runp->program->tween.time;
321 if (t > FROM_INT(1)) t = FROM_INT(1);
322 EINA_LIST_FOREACH(runp->program->targets, l, pt)
326 rp = ed->table_parts[pt->id % ed->table_parts_size];
327 if (rp) _edje_part_pos_set(ed, rp,
328 runp->program->tween.mode, t,
329 runp->program->tween.v1,
330 runp->program->tween.v2);
333 if (t >= FROM_INT(1))
335 Edje_Program_After *pa;
337 EINA_LIST_FOREACH(runp->program->targets, l, pt)
341 rp = ed->table_parts[pt->id % ed->table_parts_size];
344 _edje_part_description_apply(ed, rp,
345 runp->program->state,
346 runp->program->value,
349 _edje_part_pos_set(ed, rp,
350 runp->program->tween.mode, ZERO,
351 runp->program->tween.v1,
352 runp->program->tween.v2);
358 runp->delete_me = EINA_TRUE;
359 if (!ed->walking_actions)
362 ed->actions = eina_list_remove(ed->actions, runp);
364 _edje_animators = eina_list_remove(_edje_animators, ed);
366 // _edje_emit(ed, "program,stop", runp->program->name);
367 if (_edje_block_break(ed))
369 if (!ed->walking_actions) free(runp);
372 EINA_LIST_FOREACH(runp->program->after, l, pa)
378 pr = ed->table_programs[pa->id % ed->table_programs_size];
379 if (pr) _edje_program_run(ed, pr, 0, "", "");
380 if (_edje_block_break(ed))
382 if (!ed->walking_actions) free(runp);
389 if (!ed->walking_actions) free(runp);
402 _edje_program_end(Edje *ed, Edje_Running_Program *runp)
405 Edje_Program_Target *pt;
406 // const char *pname = NULL;
409 if (ed->delete_me) return;
412 EINA_LIST_FOREACH(runp->program->targets, l, pt)
418 rp = ed->table_parts[pt->id % ed->table_parts_size];
421 _edje_part_description_apply(ed, rp,
422 runp->program->state,
423 runp->program->value,
426 _edje_part_pos_set(ed, rp,
427 runp->program->tween.mode, ZERO,
428 runp->program->tween.v1,
429 runp->program->tween.v2);
435 runp->delete_me = EINA_TRUE;
436 // pname = runp->program->name;
437 if (!ed->walking_actions)
440 ed->actions = eina_list_remove(ed->actions, runp);
444 _edje_animators = eina_list_remove(_edje_animators, ed);
447 // _edje_emit(ed, "program,stop", pname);
450 if (free_runp) free(runp);
454 _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig, const char *ssrc)
458 Edje_Program_Target *pt;
460 Edje_Program_After *pa;
461 /* limit self-feeding loops in programs to 64 levels */
462 static int recursions = 0;
463 static int recursion_limit = 0;
465 if (ed->delete_me) return;
466 if ((pr->in.from > 0.0) && (pr->in.range >= 0.0) && (!force))
468 Edje_Pending_Program *pp;
471 pp = calloc(1, sizeof(Edje_Pending_Program));
473 if (pr->in.range > 0.0) r = ((double)rand() / RAND_MAX);
474 pp->timer = ecore_timer_add(pr->in.from + (pr->in.range * r),
475 _edje_pending_timer_cb, pp);
483 ed->pending_actions = eina_list_append(ed->pending_actions, pp);
486 if ((recursions >= 64) || (recursion_limit))
488 ERR("Programs recursing up to recursion limit of %i in '%s' with '%s', '%s' from '%s', '%s'. Disabled.",
489 64, pr->name, ssig, ssrc, ed->path, ed->group);
499 case EDJE_ACTION_TYPE_STATE_SET:
500 if ((pr->tween.time > ZERO) && (!ed->no_anim))
502 Edje_Running_Program *runp;
504 runp = calloc(1, sizeof(Edje_Running_Program));
505 EINA_LIST_FOREACH(pr->targets, l, pt)
509 rp = ed->table_parts[pt->id % ed->table_parts_size];
512 if ((rp->object) && (pr->tween.mode & EDJE_TWEEN_MODE_OPT_FROM_CURRENT))
514 Edje_Calc_Params *tmp;
516 tmp = calloc(1, sizeof(Edje_Calc_Params));
517 if (!tmp) goto low_mem_current;
518 _edje_part_recalc(ed, rp, FLAG_XY, tmp);
520 if (rp->current) free(rp->current);
523 rp->current->x -= ed->x;
524 rp->current->y -= ed->y;
525 rp->current->map.center.x -= ed->x;
526 rp->current->map.center.y -= ed->y;
527 rp->current->map.light.x -= ed->x;
528 rp->current->map.light.y -= ed->y;
529 rp->current->map.persp.x -= ed->x;
530 rp->current->map.persp.y -= ed->y;
535 if (rp->current) free(rp->current);
540 _edje_program_end(ed, rp->program);
541 _edje_part_description_apply(ed, rp,
542 rp->param1.description->state.name,
543 rp->param1.description->state.value,
546 _edje_part_pos_set(ed, rp, pr->tween.mode, ZERO,
553 // _edje_emit(ed, "program,start", pr->name);
554 if (_edje_block_break(ed))
556 ed->actions = eina_list_append(ed->actions, runp);
560 _edje_animators = eina_list_append(_edje_animators, ed);
561 ed->actions = eina_list_append(ed->actions, runp);
562 runp->start_time = ecore_loop_time_get();
566 _edje_timer = ecore_animator_add(_edje_timer_cb, NULL);
571 EINA_LIST_FOREACH(pr->targets, l, pt)
575 rp = ed->table_parts[pt->id % ed->table_parts_size];
579 _edje_program_end(ed, rp->program);
580 _edje_part_description_apply(ed, rp,
585 _edje_part_pos_set(ed, rp, pr->tween.mode, ZERO,
591 // _edje_emit(ed, "program,start", pr->name);
592 if (_edje_block_break(ed)) goto break_prog;
593 // _edje_emit(ed, "program,stop", pr->name);
594 if (_edje_block_break(ed)) goto break_prog;
596 EINA_LIST_FOREACH(pr->after, l, pa)
600 pr2 = ed->table_programs[pa->id % ed->table_programs_size];
601 if (pr2) _edje_program_run(ed, pr2, 0, "", "");
602 if (_edje_block_break(ed)) goto break_prog;
608 case EDJE_ACTION_TYPE_ACTION_STOP:
609 // _edje_emit(ed, "program,start", pr->name);
610 EINA_LIST_FOREACH(pr->targets, l, pt)
613 Edje_Running_Program *runp;
614 Edje_Pending_Program *pp;
616 for (ll = ed->actions; ll; )
620 if (pt->id == runp->program->id)
622 _edje_program_end(ed, runp);
626 for (ll = ed->pending_actions; ll; )
630 if (pt->id == pp->program->id)
632 ed->pending_actions = eina_list_remove(ed->pending_actions, pp);
633 ecore_timer_del(pp->timer);
641 // _edje_emit(ed, "program,stop", pr->name);
642 if (_edje_block_break(ed)) goto break_prog;
644 case EDJE_ACTION_TYPE_SIGNAL_EMIT:
645 // _edje_emit(ed, "program,start", pr->name);
646 if (_edje_block_break(ed)) goto break_prog;
647 _edje_emit(ed, pr->state, pr->state2);
648 if (_edje_block_break(ed)) goto break_prog;
649 // _edje_emit(ed, "program,stop", pr->name);
650 if (_edje_block_break(ed)) goto break_prog;
652 case EDJE_ACTION_TYPE_DRAG_VAL_SET:
653 // _edje_emit(ed, "program,start", pr->name);
654 if (_edje_block_break(ed)) goto break_prog;
655 EINA_LIST_FOREACH(pr->targets, l, pt)
659 rp = ed->table_parts[pt->id % ed->table_parts_size];
660 if ((rp) && (rp->drag) && (rp->drag->down.count == 0))
662 rp->drag->val.x = pr->value;
663 rp->drag->val.y = pr->value2;
664 if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0;
665 else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0;
666 if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0;
667 else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0;
668 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
669 _edje_emit(ed, "drag,set", rp->part->name);
670 if (_edje_block_break(ed)) goto break_prog;
674 // _edje_emit(ed, "program,stop", pr->name);
675 if (_edje_block_break(ed)) goto break_prog;
677 case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
678 // _edje_emit(ed, "program,start", pr->name);
679 if (_edje_block_break(ed)) goto break_prog;
680 EINA_LIST_FOREACH(pr->targets, l, pt)
684 rp = ed->table_parts[pt->id % ed->table_parts_size];
685 if ((rp) && (rp->drag) && (rp->drag->down.count == 0))
687 rp->drag->val.x += pr->value * rp->drag->step.x * rp->part->dragable.x;
688 rp->drag->val.y += pr->value2 * rp->drag->step.y * rp->part->dragable.y;
689 if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0;
690 else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0;
691 if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0;
692 else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0;
693 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
694 _edje_emit(ed, "drag,step", rp->part->name);
695 if (_edje_block_break(ed)) goto break_prog;
699 // _edje_emit(ed, "program,stop", pr->name);
700 if (_edje_block_break(ed)) goto break_prog;
702 case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
703 // _edje_emit(ed, "program,start", pr->name);
704 if (_edje_block_break(ed)) goto break_prog;
705 EINA_LIST_FOREACH(pr->targets, l, pt)
709 rp = ed->table_parts[pt->id % ed->table_parts_size];
710 if ((rp) && (rp->drag) && (rp->drag->down.count == 0))
712 rp->drag->val.x += pr->value * rp->drag->page.x * rp->part->dragable.x;
713 rp->drag->val.y += pr->value2 * rp->drag->page.y * rp->part->dragable.y;
714 if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0;
715 else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0;
716 if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0;
717 else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0;
718 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
719 _edje_emit(ed, "drag,page", rp->part->name);
720 if (_edje_block_break(ed)) goto break_prog;
724 // _edje_emit(ed, "program,stop", pr->name);
725 if (_edje_block_break(ed)) goto break_prog;
727 case EDJE_ACTION_TYPE_SCRIPT:
731 // _edje_emit(ed, "program,start", pr->name);
732 if (_edje_block_break(ed)) goto break_prog;
733 snprintf(fname, sizeof(fname), "_p%i", pr->id);
734 _edje_embryo_test_run(ed, fname, ssig, ssrc);
735 // _edje_emit(ed, "program,stop", pr->name);
736 if (_edje_block_break(ed)) goto break_prog;
740 case EDJE_ACTION_TYPE_FOCUS_SET:
742 ed->focused_part = NULL;
745 EINA_LIST_FOREACH(pr->targets, l, pt)
749 rp = ed->table_parts[pt->id % ed->table_parts_size];
752 if (ed->focused_part != rp)
754 if (ed->focused_part)
755 _edje_emit(ed, "focus,part,out",
756 ed->focused_part->part->name);
757 ed->focused_part = rp;
758 _edje_emit(ed, "focus,part,in",
759 ed->focused_part->part->name);
766 case EDJE_ACTION_TYPE_FOCUS_OBJECT:
769 Evas_Object *focused;
771 focused = evas_focus_get(evas_object_evas_get(ed->obj));
776 /* Check if the current swallowed object is one of my child. */
777 for (i = 0; i < ed->table_parts_size; ++i)
779 rp = ed->table_parts[i];
781 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
782 (rp->typedata.swallow)) &&
783 (rp->typedata.swallow->swallowed_object == focused))
785 evas_object_focus_set(focused, EINA_FALSE);
793 EINA_LIST_FOREACH(pr->targets, l, pt)
797 rp = ed->table_parts[pt->id % ed->table_parts_size];
799 ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
800 (rp->typedata.swallow)) &&
801 (rp->typedata.swallow->swallowed_object))
802 evas_object_focus_set(rp->typedata.swallow->swallowed_object, EINA_TRUE);
807 case EDJE_ACTION_TYPE_SOUND_SAMPLE:
808 if (_edje_block_break(ed))
810 if (!multisense_init) _edje_multisense_init();
811 _edje_multisense_internal_sound_sample_play(ed, pr->sample_name, pr->speed);
813 case EDJE_ACTION_TYPE_SOUND_TONE:
814 if (_edje_block_break(ed))
816 if (!multisense_init) _edje_multisense_init();
817 _edje_multisense_internal_sound_tone_play(ed, pr->tone_name, pr->duration);
819 case EDJE_ACTION_TYPE_PARAM_COPY:
821 Edje_Real_Part *src_part, *dst_part;
823 // _edje_emit(ed, "program,start", pr->name);
824 if (_edje_block_break(ed)) goto break_prog;
826 src_part = ed->table_parts[pr->param.src % ed->table_parts_size];
827 dst_part = ed->table_parts[pr->param.dst % ed->table_parts_size];
828 _edje_param_copy(src_part, pr->state, dst_part, pr->state2);
830 if (_edje_block_break(ed)) goto break_prog;
831 // _edje_emit(ed, "program,stop", pr->name);
832 if (_edje_block_break(ed)) goto break_prog;
835 case EDJE_ACTION_TYPE_PARAM_SET:
837 Edje_Real_Part *part;
839 // _edje_emit(ed, "program,start", pr->name);
840 if (_edje_block_break(ed)) goto break_prog;
842 part = ed->table_parts[pr->param.dst % ed->table_parts_size];
843 _edje_param_set(part, pr->state, pr->state2);
845 if (_edje_block_break(ed)) goto break_prog;
846 // _edje_emit(ed, "program,stop", pr->name);
847 if (_edje_block_break(ed)) goto break_prog;
851 // _edje_emit(ed, "program,start", pr->name);
852 // _edje_emit(ed, "program,stop", pr->name);
855 if (!((pr->action == EDJE_ACTION_TYPE_STATE_SET)
856 /* hmm this fucks somethgin up. must look into it later */
857 /* && (pr->tween.time > ZERO) && (!ed->no_anim))) */
860 EINA_LIST_FOREACH(pr->after, l, pa)
864 pr2 = ed->table_programs[pa->id % ed->table_programs_size];
865 if (pr2) _edje_program_run(ed, pr2, 0, "", "");
866 if (_edje_block_break(ed)) goto break_prog;
874 if (recursions == 0) recursion_limit = 0;
879 _edje_emit(Edje *ed, const char *sig, const char *src)
881 _edje_emit_full(ed, sig, src, NULL, NULL);
884 /* data should either be NULL or a malloc allocated data */
886 _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*free_func)(void *))
888 Edje_Message_Signal emsg;
891 if (ed->delete_me) return;
893 sep = strchr(sig, EDJE_PART_PATH_SEPARATOR);
895 /* If we are not sending the signal to a part of the child, the
896 * signal if for ourself
900 Edje_Real_Part *rp = NULL;
907 /* the signal contains a colon, split the signal into "parts:signal" */
908 length = sep - sig + 1;
909 part = alloca(length);
910 memcpy(part, sig, length - 1);
911 part[length - 1] = '\0';
915 /* lookup for alias */
916 if (ed->collection && ed->collection->alias)
920 alias = eina_hash_find(ed->collection->alias, part);
926 alien = strlen(alias);
927 nslen = strlen(newsig);
928 length = alien + nslen + 2;
930 aliased = alloca(length);
931 memcpy(aliased, alias, alien);
932 aliased[alien] = EDJE_PART_PATH_SEPARATOR;
933 memcpy(aliased + alien + 1, newsig, nslen + 1);
935 _edje_emit(ed, aliased, src);
940 /* search for the index if present and remove it from the part */
941 idx = strchr(part, EDJE_PART_PATH_SEPARATOR_INDEXL);
946 end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR);
947 if (end && end != idx + 1)
951 tmp = alloca(end - idx - 1);
952 memcpy(tmp, idx + 1, end - idx - 1);
953 tmp[end - idx - 1] = '\0';
963 /* search for the right part now */
964 rp = _edje_real_part_get(ed, part);
967 switch (rp->part->type)
969 case EDJE_PART_TYPE_GROUP:
970 if (((rp->type != EDJE_RP_TYPE_SWALLOW) ||
971 (!rp->typedata.swallow)) ||
972 (!rp->typedata.swallow->swallowed_object))
974 ed2 = _edje_fetch(rp->typedata.swallow->swallowed_object);
977 _edje_emit(ed2, newsig, src);
980 case EDJE_PART_TYPE_EXTERNAL:
981 if (((rp->type != EDJE_RP_TYPE_SWALLOW) ||
982 (!rp->typedata.swallow)) ||
983 (!rp->typedata.swallow->swallowed_object))
988 _edje_external_signal_emit(rp->typedata.swallow->swallowed_object, newsig, src);
994 child = _edje_children_get(rp, idx);
995 ed2 = _edje_fetch(child);
997 _edje_emit(ed2, newsig, src);
1001 case EDJE_PART_TYPE_BOX:
1002 case EDJE_PART_TYPE_TABLE:
1007 child = _edje_children_get(rp, idx);
1008 ed2 = _edje_fetch(child);
1010 _edje_emit(ed2, newsig, src);
1015 // ERR("SPANK SPANK SPANK !!!\nYou should never be here !");
1025 emsg.data = calloc(1, sizeof(*(emsg.data)));
1027 emsg.data->data = data;
1028 emsg.data->free_func = free_func;
1034 /* new sends code */
1035 edje_object_message_send(ed->obj, EDJE_MESSAGE_SIGNAL, 0, &emsg);
1036 /* old send code - use api now
1037 _edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
1038 EINA_LIST_FOREACH(ed->subobjs, l, obj)
1042 ed2 = _edje_fetch(obj);
1044 if (ed2->delete_me) continue;
1045 _edje_message_send(ed2, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);
1048 if (emsg.data && (--(emsg.data->ref) == 0))
1050 if (emsg.data->free_func)
1052 emsg.data->free_func(emsg.data->data);
1058 struct _Edje_Program_Data
1065 static Eina_Bool _edje_glob_callback(Edje_Program *pr, void *dt)
1067 struct _Edje_Program_Data *data = dt;
1068 Edje_Real_Part *rp = NULL;
1069 Eina_Bool exec = EINA_TRUE;
1071 if (pr->filter.state)
1073 rp = _edje_real_part_get(data->ed, pr->filter.part ? pr->filter.part : data->source);
1075 exec = (rp->chosen_description->state.name == pr->filter.state);
1080 data->matches = eina_list_append(data->matches, pr);
1086 _edje_callbacks_patterns_clean(Edje *ed)
1088 if (ed->walking_callbacks > 0) return;
1090 _edje_signals_sources_patterns_clean(&ed->patterns.callbacks);
1092 eina_rbtree_delete(ed->patterns.callbacks.exact_match,
1093 EINA_RBTREE_FREE_CB(edje_match_signal_source_free),
1095 ed->patterns.callbacks.exact_match = NULL;
1097 ed->patterns.callbacks.u.callbacks.globing = eina_list_free(ed->patterns.callbacks.u.callbacks.globing);
1101 _edje_callbacks_patterns_init(Edje *ed)
1103 Edje_Signals_Sources_Patterns *ssp = &ed->patterns.callbacks;
1105 if ((ssp->signals_patterns) || (ssp->sources_patterns) ||
1106 (ssp->u.callbacks.globing) || (ssp->exact_match))
1109 ssp->u.callbacks.globing = edje_match_callback_hash_build(ed->callbacks,
1112 ssp->signals_patterns = edje_match_callback_signal_init(ssp->u.callbacks.globing);
1113 ssp->sources_patterns = edje_match_callback_source_init(ssp->u.callbacks.globing);
1116 /* FIXME: what if we delete the evas object??? */
1118 _edje_emit_handle(Edje *ed, const char *sig, const char *src,
1119 Edje_Message_Signal_Data *sdata, Eina_Bool prop)
1121 if (ed->delete_me) return;
1124 // printf("EDJE EMIT: (%p) signal: \"%s\" source: \"%s\"\n", ed, sig, src);
1129 if (ed->collection && ed->L)
1130 _edje_lua2_script_func_signal(ed, sig, src);
1134 #ifdef EDJE_PROGRAM_CACHE
1135 Edje_Part_Collection *ec;
1141 #ifdef EDJE_PROGRAM_CACHE
1142 ec = ed->collection;
1145 tmps = alloca(l1 + l2 + 3); /* \0, \337, \0 */
1148 strcpy(&(tmps[l1 + 1]), src);
1152 #ifdef EDJE_PROGRAM_CACHE
1158 if (eina_hash_find(ec->prog_cache.no_matches, tmps))
1162 else if ((matches = eina_hash_find(ec->prog_cache.matches, tmps)))
1164 EINA_LIST_FOREACH(matches, l, pr)
1166 Eina_Bool exec = EINA_TRUE;
1168 if (pr->filter.state)
1172 rp = _edje_real_part_get(ed, pr->filter.part ? pr->filter.part : src);
1178 exec = (rp->chosen_description->state.name == pr->filter.state);
1185 EINA_LIST_FOREACH(matches, l, pr)
1188 _edje_program_run(ed, pr, 0, sig, src);
1189 if (_edje_block_break(ed))
1201 struct _Edje_Program_Data data;
1205 data.matches = NULL;
1207 if (ed->table_programs_size > 0)
1209 const Eina_Array *match;
1210 #ifdef EDJE_PROGRAM_CACHE
1214 Eina_Array_Iterator iterator;
1217 if (ed->patterns.programs.u.programs.globing)
1218 if (edje_match_programs_exec(ed->patterns.programs.signals_patterns,
1219 ed->patterns.programs.sources_patterns,
1222 ed->patterns.programs.u.programs.globing,
1223 _edje_glob_callback,
1228 match = edje_match_signal_source_hash_get(sig, src,
1229 ed->patterns.programs.exact_match);
1231 EINA_ARRAY_ITER_NEXT(match, i, pr, iterator)
1232 _edje_glob_callback(pr, &data);
1234 #ifdef EDJE_PROGRAM_CACHE
1235 EINA_LIST_FOREACH(data.matches, l, pr)
1237 EINA_LIST_FREE(data.matches, pr)
1241 _edje_program_run(ed, pr, 0, sig, src);
1243 if (_edje_block_break(ed))
1245 eina_list_free(data.matches);
1246 data.matches = NULL;
1252 #ifdef EDJE_PROGRAM_CACHE
1255 if (data.matches == NULL)
1257 if (!ec->prog_cache.no_matches)
1258 ec->prog_cache.no_matches = eina_hash_string_superfast_new(NULL);
1259 eina_hash_add(ec->prog_cache.no_matches, tmps, ed);
1263 if (!ec->prog_cache.matches)
1264 ec->prog_cache.matches = eina_hash_string_superfast_new(NULL);
1265 eina_hash_add(ec->prog_cache.matches, tmps, data.matches);
1270 _edje_emit_cb(ed, sig, src, sdata, prop);
1271 if (_edje_block_break(ed))
1282 /* Extra data for callbacks */
1283 static void *callback_extra_data = NULL;
1286 edje_object_signal_callback_extra_data_get(void)
1288 return callback_extra_data;
1291 /* FIXME: what if we delete the evas object??? */
1293 _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop)
1297 if (ed->delete_me) return;
1302 if (ed->just_added_callbacks)
1303 _edje_callbacks_patterns_clean(ed);
1305 ed->walking_callbacks++;
1309 Edje_Signal_Callback *escb;
1310 const Eina_Array *match;
1311 Eina_Array_Iterator iterator;
1314 callback_extra_data = (data) ? data->data : NULL;
1316 _edje_callbacks_patterns_init(ed);
1317 if (ed->patterns.callbacks.u.callbacks.globing)
1318 r = edje_match_callback_exec(ed->patterns.callbacks.signals_patterns,
1319 ed->patterns.callbacks.sources_patterns,
1322 ed->patterns.callbacks.u.callbacks.globing,
1329 match = edje_match_signal_source_hash_get(sig, src,
1330 ed->patterns.callbacks.exact_match);
1332 EINA_ARRAY_ITER_NEXT(match, i, escb, iterator)
1334 if ((prop) && (escb->propagate)) continue;
1335 if ((!escb->just_added) && (!escb->delete_me))
1337 escb->func(escb->data, ed->obj, sig, src);
1338 if (_edje_block_break(ed))
1345 ed->walking_callbacks--;
1346 if (!ed->walking_callbacks &&
1347 ((ed->delete_callbacks) || (ed->just_added_callbacks)))
1349 ed->delete_callbacks = EINA_FALSE;
1350 ed->just_added_callbacks = EINA_FALSE;
1354 Edje_Signal_Callback *escb = l->data;
1355 Eina_List *next_l = l->next;
1357 if (escb->just_added)
1358 escb->just_added = 0;
1359 if (escb->delete_me)
1361 ed->callbacks = eina_list_remove_list(ed->callbacks, l);
1362 if (escb->signal) eina_stringshare_del(escb->signal);
1363 if (escb->source) eina_stringshare_del(escb->source);
1369 _edje_callbacks_patterns_clean(ed);
1376 static const Edje_External_Param_Info *
1377 _edje_external_param_info_get(const Evas_Object *obj, const char *name)
1379 const Edje_External_Type *type;
1380 const Edje_External_Param_Info *info;
1382 type = evas_object_data_get(obj, "Edje_External_Type");
1383 if (!type) return NULL;
1384 for (info = type->parameters_info; info->name; info++)
1385 if (!strcmp(info->name, name)) return info;
1390 static Edje_External_Param *
1391 _edje_param_external_get(Edje_Real_Part *rp, const char *name, Edje_External_Param *param)
1393 Evas_Object *swallowed_object;
1394 const Edje_External_Param_Info *info;
1396 if ((rp->type != EDJE_RP_TYPE_SWALLOW) ||
1397 (!rp->typedata.swallow)) return NULL;
1398 swallowed_object = rp->typedata.swallow->swallowed_object;
1400 info = _edje_external_param_info_get(swallowed_object, name);
1401 if (!info) return NULL;
1403 memset(param, 0, sizeof(*param));
1404 param->name = info->name;
1405 param->type = info->type;
1406 if (!_edje_external_param_get(NULL, rp, param)) return NULL;
1410 /* simulate external properties for native objects */
1411 static Edje_External_Param *
1412 _edje_param_native_get(Edje_Real_Part *rp, const char *name, Edje_External_Param *param, void **free_ptr)
1415 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
1416 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
1418 if (!strcmp(name, "text"))
1421 param->type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
1423 _edje_recalc_do(rp->edje);
1424 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1425 param->s = _edje_entry_text_get(rp);
1426 else if ((rp->part->type == EDJE_PART_TYPE_TEXT) &&
1427 ((rp->type == EDJE_RP_TYPE_TEXT) &&
1428 (rp->typedata.text)))
1429 param->s = rp->typedata.text->text;
1431 param->s = evas_object_textblock_text_markup_get(rp->object);
1434 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1436 if (!strcmp(name, "text_unescaped"))
1439 param->type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
1441 _edje_recalc_do(rp->edje);
1442 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
1444 const char *tmp = _edje_entry_text_get(rp);
1445 char *unescaped = _edje_text_unescape(tmp);
1446 *free_ptr = unescaped;
1447 param->s = unescaped;
1449 else if ((rp->part->type == EDJE_PART_TYPE_TEXT) &&
1450 ((rp->type == EDJE_RP_TYPE_TEXT) &&
1451 (rp->typedata.text)))
1452 param->s = rp->typedata.text->text;
1458 tmp = evas_object_textblock_text_markup_get(rp->object);
1459 unescaped = _edje_text_unescape(tmp);
1460 *free_ptr = unescaped;
1461 param->s = unescaped;
1467 if (((rp->type == EDJE_RP_TYPE_TEXT) &&
1468 (rp->typedata.text)) &&
1469 ((rp->typedata.text->entry_data) &&
1470 (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) &&
1471 (!strcmp(name, "select_allow"))))
1474 param->type = EDJE_EXTERNAL_PARAM_TYPE_BOOL;
1475 param->i = _edje_entry_select_allow_get(rp);
1481 if ((rp->drag) && (rp->drag->down.count == 0))
1483 if (!strncmp(name, "drag_", sizeof("drag_") - 1))
1485 const char *sub_name = name + sizeof("drag_") - 1;
1486 if (!strcmp(sub_name, "value_x"))
1490 _edje_recalc_do(rp->edje);
1491 d = TO_DOUBLE(rp->drag->val.x);
1492 if (rp->part->dragable.x < 0) d = 1.0 - d;
1494 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1498 if (!strcmp(sub_name, "value_y"))
1502 _edje_recalc_do(rp->edje);
1503 d = TO_DOUBLE(rp->drag->val.y);
1504 if (rp->part->dragable.y < 0) d = 1.0 - d;
1506 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1511 if (!strcmp(sub_name, "size_w"))
1513 _edje_recalc_do(rp->edje);
1515 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1516 param->d = TO_DOUBLE(rp->drag->size.x);
1519 if (!strcmp(sub_name, "size_h"))
1521 _edje_recalc_do(rp->edje);
1523 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1524 param->d = TO_DOUBLE(rp->drag->size.y);
1528 if (!strcmp(sub_name, "step_x"))
1530 _edje_recalc_do(rp->edje);
1532 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1533 param->d = TO_DOUBLE(rp->drag->step.x);
1536 if (!strcmp(sub_name, "step_y"))
1538 _edje_recalc_do(rp->edje);
1540 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1541 param->d = TO_DOUBLE(rp->drag->step.y);
1545 if (!strcmp(sub_name, "page_x"))
1547 _edje_recalc_do(rp->edje);
1549 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1550 param->d = TO_DOUBLE(rp->drag->page.x);
1553 if (!strcmp(sub_name, "page_y"))
1555 _edje_recalc_do(rp->edje);
1557 param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
1558 param->d = TO_DOUBLE(rp->drag->page.y);
1570 _edje_param_native_set(Edje_Real_Part *rp, const char *name, const Edje_External_Param *param)
1572 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
1573 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
1575 if (!strcmp(name, "text"))
1577 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_STRING)
1580 _edje_object_part_text_raw_set
1581 (rp->edje->obj, rp, rp->part->name, param->s);
1584 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1586 if (!strcmp(name, "text_unescaped"))
1588 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_STRING)
1591 if (rp->part->type == EDJE_PART_TYPE_TEXT)
1592 _edje_object_part_text_raw_set
1593 (rp->edje->obj, rp, rp->part->name, param->s);
1596 char *escaped = _edje_text_escape(param->s);
1597 _edje_object_part_text_raw_set
1598 (rp->edje->obj, rp, rp->part->name, escaped);
1605 if (((rp->type == EDJE_RP_TYPE_TEXT) &&
1606 (rp->typedata.text)) &&
1607 ((rp->typedata.text->entry_data) &&
1608 (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) &&
1609 (!strcmp(name, "select_allow"))))
1611 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_BOOL)
1613 _edje_entry_select_allow_set(rp, param->i);
1619 if ((rp->drag) && (rp->drag->down.count == 0))
1621 if (!strncmp(name, "drag_", sizeof("drag_") - 1))
1623 const char *sub_name = name + sizeof("drag_") - 1;
1624 if (!strcmp(sub_name, "value_x"))
1627 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1630 if (rp->part->dragable.confine_id != -1)
1631 d = CLAMP(d, 0.0, 1.0);
1632 if (rp->part->dragable.x < 0) d = 1.0 - d;
1633 if (rp->drag->val.x == FROM_DOUBLE(d)) return EINA_TRUE;
1634 rp->drag->val.x = FROM_DOUBLE(d);
1635 #ifdef EDJE_CALC_CACHE
1638 _edje_dragable_pos_set
1639 (rp->edje, rp, rp->drag->val.x, rp->drag->val.y);
1640 _edje_emit(rp->edje, "drag,set", rp->part->name);
1643 if (!strcmp(sub_name, "value_y"))
1646 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1649 if (rp->part->dragable.confine_id != -1)
1650 d = CLAMP(d, 0.0, 1.0);
1651 if (rp->part->dragable.y < 0) d = 1.0 - d;
1652 if (rp->drag->val.y == FROM_DOUBLE(d)) return EINA_TRUE;
1653 rp->drag->val.y = FROM_DOUBLE(d);
1654 #ifdef EDJE_CALC_CACHE
1657 _edje_dragable_pos_set
1658 (rp->edje, rp, rp->drag->val.x, rp->drag->val.y);
1659 _edje_emit(rp->edje, "drag,set", rp->part->name);
1663 if (!strcmp(sub_name, "size_w"))
1665 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1667 rp->drag->size.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1668 rp->edje->recalc_call = EINA_TRUE;
1669 rp->edje->dirty = EINA_TRUE;
1670 #ifdef EDJE_CALC_CACHE
1673 _edje_recalc(rp->edje);
1676 if (!strcmp(sub_name, "size_h"))
1678 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1680 rp->drag->size.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1681 rp->edje->recalc_call = EINA_TRUE;
1682 rp->edje->dirty = EINA_TRUE;
1683 #ifdef EDJE_CALC_CACHE
1686 _edje_recalc(rp->edje);
1690 if (!strcmp(sub_name, "step_x"))
1692 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1694 rp->drag->step.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1695 #ifdef EDJE_CALC_CACHE
1700 if (!strcmp(sub_name, "step_y"))
1702 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1704 rp->drag->step.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1705 #ifdef EDJE_CALC_CACHE
1711 if (!strcmp(sub_name, "page_x"))
1713 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1715 rp->drag->page.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1716 #ifdef EDJE_CALC_CACHE
1721 if (!strcmp(sub_name, "page_y"))
1723 if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
1725 rp->drag->page.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0));
1726 #ifdef EDJE_CALC_CACHE
1739 static const Edje_External_Param_Info *
1740 _edje_native_param_info_get(const Edje_Real_Part *rp, const char *name)
1742 if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
1743 (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
1745 if (!strcmp(name, "text"))
1747 static const Edje_External_Param_Info pi =
1748 EDJE_EXTERNAL_PARAM_INFO_STRING("text");
1751 if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1753 if (!strcmp(name, "text_unescaped"))
1755 static const Edje_External_Param_Info pi =
1756 EDJE_EXTERNAL_PARAM_INFO_STRING("text_unescaped");
1759 if (!strcmp(name, "select_allow"))
1761 static const Edje_External_Param_Info pi =
1762 EDJE_EXTERNAL_PARAM_INFO_BOOL("text_unescaped");
1768 if ((rp->drag) && (rp->drag->down.count == 0))
1770 if (!strncmp(name, "drag_", sizeof("drag_") - 1))
1772 name += sizeof("drag_") - 1;
1773 if (!strcmp(name, "value_x"))
1775 static const Edje_External_Param_Info pi =
1776 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_x");
1779 if (!strcmp(name, "value_y"))
1781 static const Edje_External_Param_Info pi =
1782 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_y");
1785 if (!strcmp(name, "size_w"))
1787 static const Edje_External_Param_Info pi =
1788 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_w");
1791 if (!strcmp(name, "size_h"))
1793 static const Edje_External_Param_Info pi =
1794 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_h");
1797 if (!strcmp(name, "step_x"))
1799 static const Edje_External_Param_Info pi =
1800 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_x");
1803 if (!strcmp(name, "step_y"))
1805 static const Edje_External_Param_Info pi =
1806 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_y");
1809 if (!strcmp(name, "page_x"))
1811 static const Edje_External_Param_Info pi =
1812 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_x");
1815 if (!strcmp(name, "page_y"))
1817 static const Edje_External_Param_Info pi =
1818 EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_y");
1829 static Edje_External_Param *
1830 _edje_param_convert(Edje_External_Param *param, const Edje_External_Param_Info *dst_info)
1832 if (param->type == dst_info->type) return param;
1834 switch (dst_info->type)
1836 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1837 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1840 switch (param->type)
1842 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1845 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1846 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1847 i = (param->s) ? atoi(param->s) : 0;
1849 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1850 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1856 if (dst_info->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
1858 param->type = dst_info->type;
1863 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1866 switch (param->type)
1868 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1869 d = (double)param->i;
1871 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1872 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1873 d = (param->s) ? atof(param->s) : 0.0;
1875 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1876 d = (double)param->i;
1881 param->type = dst_info->type;
1886 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1889 switch (param->type)
1891 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1892 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1893 if (!snprintf(s, sizeof(s), "%i", param->i)) return NULL;
1895 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1896 if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL;
1898 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1899 param->type = dst_info->type;
1904 param->type = dst_info->type;
1909 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1913 switch (param->type)
1915 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1916 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1917 if (!snprintf(s, sizeof(s), "%i", param->i)) return NULL;
1920 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1921 if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL;
1924 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1931 param->type = dst_info->type;
1932 if (param->s != val) param->s = val;
1936 default: return NULL;
1941 _edje_param_validate(const Edje_External_Param *param, const Edje_External_Param_Info *info)
1945 case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
1946 return ((param->i == 0) || (param->i == 1));
1948 case EDJE_EXTERNAL_PARAM_TYPE_INT:
1949 if ((info->info.i.min != EDJE_EXTERNAL_INT_UNSET) &&
1950 (info->info.i.min > param->i))
1953 if ((info->info.i.max != EDJE_EXTERNAL_INT_UNSET) &&
1954 (info->info.i.max < param->i))
1959 case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
1960 if ((info->info.d.min != EDJE_EXTERNAL_DOUBLE_UNSET) &&
1961 (info->info.d.min > param->d))
1964 if ((info->info.d.max != EDJE_EXTERNAL_DOUBLE_UNSET) &&
1965 (info->info.d.max < param->d))
1970 case EDJE_EXTERNAL_PARAM_TYPE_STRING:
1971 if (!param->s) return EINA_FALSE;
1972 if (info->info.s.accept_fmt)
1973 INF("string 'accept_fmt' validation not implemented.");
1974 if (info->info.s.deny_fmt)
1975 INF("string 'deny_fmt' validation not implemented.");
1978 case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
1980 const char **itr = info->info.c.choices;
1981 if (!itr) return EINA_FALSE;
1983 if (!strcmp(*itr, param->s))
1988 default: return EINA_FALSE;
1993 _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param)
1995 Edje_External_Param val;
1996 const Edje_External_Param_Info *dst_info;
1997 void *free_ptr = NULL;
1999 if ((!src_part) || (!src_param) || (!dst_part) || (!dst_param))
2002 if ((dst_part->part->type == EDJE_PART_TYPE_EXTERNAL) &&
2003 (dst_part->type == EDJE_RP_TYPE_SWALLOW) &&
2004 (dst_part->typedata.swallow))
2005 dst_info = _edje_external_param_info_get
2006 (dst_part->typedata.swallow->swallowed_object, dst_param);
2008 dst_info = _edje_native_param_info_get(dst_part, dst_param);
2012 ERR("cannot copy, invalid destination parameter '%s' of part '%s'",
2013 dst_param, dst_part->part->name);
2017 if (src_part->part->type == EDJE_PART_TYPE_EXTERNAL)
2019 if (!_edje_param_external_get
2020 (src_part, src_param, &val))
2022 ERR("cannot get parameter '%s' of part '%s'",
2023 src_param, src_part->part->name);
2029 if (!_edje_param_native_get(src_part, src_param, &val, &free_ptr))
2031 ERR("cannot get parameter '%s' of part '%s'",
2032 src_param, src_part->part->name);
2037 if (!_edje_param_convert(&val, dst_info))
2039 ERR("cannot convert parameter type %s to requested type %s",
2040 edje_external_param_type_str(val.type),
2041 edje_external_param_type_str(dst_info->type));
2045 if (!_edje_param_validate(&val, dst_info))
2047 ERR("incorrect parameter value failed validation for type %s",
2048 edje_external_param_type_str(dst_info->type));
2052 if (dst_part->part->type == EDJE_PART_TYPE_EXTERNAL)
2054 val.name = dst_param;
2055 if (!_edje_external_param_set(NULL, dst_part, &val))
2057 ERR("failed to set parameter '%s' (%s) of part '%s'",
2058 dst_param, edje_external_param_type_str(dst_info->type),
2059 dst_part->part->name);
2065 if (!_edje_param_native_set(dst_part, dst_param, &val))
2067 ERR("failed to set parameter '%s' (%s) of part '%s'",
2068 dst_param, edje_external_param_type_str(dst_info->type),
2069 dst_part->part->name);
2079 _edje_param_set(Edje_Real_Part *part, const char *param, const char *value)
2081 Edje_External_Param val;
2082 const Edje_External_Param_Info *info;
2084 if ((!part) || (!param) || (!value))
2087 if ((part->part->type == EDJE_PART_TYPE_EXTERNAL) &&
2088 (part->type == EDJE_RP_TYPE_SWALLOW) &&
2089 (part->typedata.swallow))
2090 info = _edje_external_param_info_get(part->typedata.swallow->swallowed_object, param);
2092 info = _edje_native_param_info_get(part, param);
2096 ERR("cannot copy, invalid destination parameter '%s' of part '%s'",
2097 param, part->part->name);
2101 val.name = "(temp)";
2102 val.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2105 if (!_edje_param_convert(&val, info))
2107 ERR("cannot convert parameter type STRING to requested type %s",
2108 edje_external_param_type_str(info->type));
2112 if (!_edje_param_validate(&val, info))
2114 ERR("incorrect parameter value failed validation for type %s",
2115 edje_external_param_type_str(info->type));
2119 if (part->part->type == EDJE_PART_TYPE_EXTERNAL)
2122 if (!_edje_external_param_set(NULL, part, &val))
2124 ERR("failed to set parameter '%s' (%s) of part '%s'",
2125 param, edje_external_param_type_str(info->type),
2132 if (!_edje_param_native_set(part, param, &val))
2134 ERR("failed to set parameter '%s' (%s) of part '%s'",
2135 param, edje_external_param_type_str(info->type),