edje: correctly propagate event recursivly with existing and non existing part.

NOTE: I don't backport it yet as I would like some test before doing so.


SVN revision: 57678
This commit is contained in:
Cedric BAIL 2011-03-10 17:27:55 +00:00
parent 0f002c7f93
commit 4b4e194be2
4 changed files with 106 additions and 133 deletions

View File

@ -51,3 +51,10 @@
2011-03-10 WooHyun Jung
* Fix: Emit clicked signal on entry if still in - missing.
2011-03-10 Cedric BAIL
* Correctly propagate recursive event with existing and non existing
part.

View File

@ -1507,7 +1507,6 @@ const char * _edje_text_class_font_get(Edje *ed,
Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part);
Edje_Real_Part *_edje_real_part_recursive_get(const Edje *ed, const char *part);
Edje *_edje_recursive_get(Edje *ed, const char *part, Edje_Real_Part **orp);
Edje_Color_Class *_edje_color_class_find(Edje *ed, const char *color_class);
void _edje_color_class_member_add(Edje *ed, const char *color_class);
void _edje_color_class_member_del(Edje *ed, const char *color_class);

View File

@ -1001,7 +1001,7 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
if (ed->delete_me) return;
sep = strrchr(sig, EDJE_PART_PATH_SEPARATOR);
sep = strchr(sig, EDJE_PART_PATH_SEPARATOR);
/* If we are not sending the signal to a part of the child, the
* signal if for ourself
@ -1009,56 +1009,119 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
if (sep)
{
Edje_Real_Part *rp = NULL;
const char *newsig;
Edje *ed2;
char *newsig;
size_t length;
char *part;
char *idx;
size_t length;
/* the signal contains a colon, split the signal into "parts:signal",
* use _edje_real_part_recursive_get_helper to find the real part.
*/
length = strlen(sig) + 1;
/* the signal contains a colon, split the signal into "parts:signal" */
length = sep - sig + 1;
part = alloca(length);
memcpy(part, sig, length);
memcpy(part, sig, length - 1);
part[length - 1] = '\0';
newsig = part + (sep - sig);
newsig = sep + 1;
*newsig = '\0';
newsig++;
ed2 = _edje_recursive_get(ed, part, &rp);
if (ed2 && ed2 != ed)
/* lookup for alias */
if (ed->collection && ed->collection->alias)
{
_edje_emit(ed2, newsig, src);
char *alias;
alias = eina_hash_find(ed->collection->alias, part);
if (alias) {
char *aliased;
int alien;
int nslen;
alien = strlen(alias);
nslen = strlen(newsig);
length = alien + nslen + 2;
aliased = alloca(length);
memcpy(aliased, alias, alien);
aliased[alien] = EDJE_PART_PATH_SEPARATOR;
memcpy(aliased + alien + 1, newsig, nslen + 1);
return _edje_emit(ed, aliased, src);
}
}
else if (rp)
/* search for the index if present and remove it from the part */
idx = strchr(part, EDJE_PART_PATH_SEPARATOR_INDEXL);
if (idx)
{
switch (rp->part->type)
char *end;
end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR);
if (end && end != idx + 1)
{
case EDJE_PART_TYPE_EXTERNAL:
if (!rp->swallowed_object) break ;
char *tmp;
_edje_external_signal_emit(rp->swallowed_object, newsig, src);
break ;
case EDJE_PART_TYPE_BOX:
case EDJE_PART_TYPE_TABLE:
_edje_emit(rp->edje, newsig, src);
break ;
case EDJE_PART_TYPE_GROUP:
if (!rp->swallowed_object) break;
ed2 = _edje_fetch(rp->swallowed_object);
if (!ed2) break;
_edje_emit(ed2, newsig, src);
break ;
default:
fprintf(stderr, "SPANK SPANK SPANK !!!\nYou should never be here !\n");
break;
tmp = alloca(end - idx - 1);
memcpy(tmp, idx + 1, end - idx - 1);
tmp[end - idx - 1] = '\0';
*idx = '\0';
idx = tmp;
}
else
{
idx = NULL;
}
}
/* search for the right part now */
rp = _edje_real_part_get(ed, part);
if (!rp) goto end;
switch (rp->part->type)
{
case EDJE_PART_TYPE_GROUP:
if (!rp->swallowed_object) goto end;
ed2 = _edje_fetch(rp->swallowed_object);
if (!ed2) goto end;
_edje_emit(ed2, newsig, src);
break;
case EDJE_PART_TYPE_EXTERNAL:
if (!rp->swallowed_object) break ;
if (!idx)
{
_edje_external_signal_emit(rp->swallowed_object, newsig, src);
}
else
{
Evas_Object *child;
child = _edje_children_get(rp, idx);
ed2 = _edje_fetch(child);
if (!ed2) goto end;
_edje_emit(ed2, newsig, src);
}
break ;
case EDJE_PART_TYPE_BOX:
case EDJE_PART_TYPE_TABLE:
if (idx)
{
Evas_Object *child;
child = _edje_children_get(rp, idx);
ed2 = _edje_fetch(child);
if (!ed2) goto end;
_edje_emit(ed2, newsig, src);
}
break ;
default:
fprintf(stderr, "SPANK SPANK SPANK !!!\nYou should never be here !\n");
break;
}
}
end:
emsg.sig = sig;
emsg.src = src;
_edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg);

View File

@ -38,7 +38,6 @@ static void _edje_object_image_preload_cb(void *data, Evas *e, Evas_Object *obj,
static void _edje_object_signal_preload_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
Edje_Real_Part *_edje_real_part_recursive_get_helper(const Edje *ed, char **path);
static Edje *_edje_recursive_get_helper(Edje *ed, char **path, Edje_Real_Part **orp);
/************************** API Routines **************************/
@ -4491,22 +4490,6 @@ _edje_real_part_recursive_get(const Edje *ed, const char *part)
return rp;
}
Edje *
_edje_recursive_get(Edje *ed, const char *part, Edje_Real_Part **orp)
{
Edje *oed;
char **path;
path = eina_str_split(part, EDJE_PART_PATH_SEPARATOR_STRING, 0);
if (!path) return NULL;
oed = _edje_recursive_get_helper(ed, path, orp);
free(*path);
free(path);
return oed;
}
Evas_Object *
_edje_children_get(Edje_Real_Part *rp, const char *partid)
{
@ -4652,85 +4635,6 @@ _edje_real_part_recursive_get_helper(const Edje *ed, char **path)
}
/* Private Routines */
static Edje *
_edje_recursive_get_helper(Edje *ed, char **path, Edje_Real_Part **orp)
{
Evas_Object *child;
Edje_Real_Part *rp;
char *idx = NULL;
if (!path[0])
return NULL;
if (ed->collection && ed->collection->alias)
{
char *alias;
alias = _edje_merge_path(eina_hash_find(ed->collection->alias, path[0]), path + 1);
if (alias) {
Edje *tmp;
tmp = _edje_recursive_get(ed, alias, orp);
free(alias);
return tmp;
}
}
//printf(" lookup: %s on %s\n", path[0], ed->parent ? ed->parent : "-");
idx = strchr(path[0], EDJE_PART_PATH_SEPARATOR_INDEXL);
if (idx)
{
char *end;
end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR);
if (end)
{
*end = '\0';
*idx = '\0';
idx++;
}
}
rp = _edje_real_part_get(ed, path[0]);
if (!rp) return NULL;
if (!path[1] && !idx)
{
*orp = rp;
return rp->edje;
}
switch (rp->part->type)
{
case EDJE_PART_TYPE_GROUP:
if (!rp->swallowed_object) return NULL;
ed = _edje_fetch(rp->swallowed_object);
if (!ed) return NULL;
path++;
if (!path[0]) return ed;
return _edje_recursive_get_helper(ed, path, orp);
case EDJE_PART_TYPE_BOX:
case EDJE_PART_TYPE_TABLE:
case EDJE_PART_TYPE_EXTERNAL:
if (!idx)
{
*orp = rp;
return NULL;
}
path++;
child = _edje_children_get(rp, idx);
ed = _edje_fetch(child);
if (!ed) return NULL;
if (!path[0]) return ed;
return _edje_recursive_get_helper(ed, path, orp);
default:
return NULL;
}
}
Edje_Real_Part *
_edje_real_part_get(const Edje *ed, const char *part)
{