* edje: improve the way to target children of box and table.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 10 Jun 2010 15:40:51 +0000 (15:40 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 10 Jun 2010 15:40:51 +0000 (15:40 +0000)
You can now adress them with somethin like part[name]:subpart
or part[index]:subpart in all signal emit code and API that
require a part to be specified.

TODO: we need to add this index/name information when a signal
is emitted from a subpart.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/edje@49614 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/edje_private.h
src/lib/edje_program.c
src/lib/edje_util.c

index 11e8882..0cbefa7 100644 (file)
@@ -309,6 +309,8 @@ typedef struct _Edje_Patterns                        Edje_Patterns;
 
 #define EDJE_PART_PATH_SEPARATOR ':'
 #define EDJE_PART_PATH_SEPARATOR_STRING ":"
+#define EDJE_PART_PATH_SEPARATOR_INDEXL '['
+#define EDJE_PART_PATH_SEPARATOR_INDEXR ']'
 /*----------*/
 
 struct _Edje_File
@@ -1395,6 +1397,7 @@ Eina_Bool         _edje_real_part_box_remove_all(Edje_Real_Part *rp, Eina_Bool c
 Eina_Bool         _edje_real_part_table_pack(Edje_Real_Part *rp, Evas_Object *child_obj, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan);
 Eina_Bool         _edje_real_part_table_unpack(Edje_Real_Part *rp, Evas_Object *child_obj);
 void              _edje_real_part_table_clear(Edje_Real_Part *rp, Eina_Bool clear);
+Evas_Object      *_edje_children_get(Edje_Real_Part *rp, const char *partid);
 
 Eina_Bool         _edje_object_part_text_raw_set(Evas_Object *obj, Edje_Real_Part *rp, const char *part, const char *text);
 char             *_edje_text_escape(const char *text);
index f1e7219..b3a7543 100644 (file)
@@ -1012,9 +1012,14 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
 
    if (ed->delete_me) return;
 
-   sep = strchr(sig, ':');
+   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
+    */
    if (sep)
      {
+       const char *idx;
         size_t length;
         char *part;
        /* the signal contains a colon, split the signal into "part:signal",
@@ -1027,16 +1032,23 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
             char *newsig;
            int i;
 
-            memcpy(part, sig, length);
-            newsig = part + (sep - sig);
+           memcpy(part, sig, length);
+
+           /* The part contain a [index], retrieve it */
+           idx = strchr(sig, EDJE_PART_PATH_SEPARATOR_INDEXL);
+           if (idx == NULL || sep < idx) newsig = part + (sep - sig);
+           else newsig = part + (idx - sig);
+
            *newsig = '\0';
            newsig++;
 
             for (i = 0; i < ed->table_parts_size; i++)
               {
                  Edje_Real_Part *rp = ed->table_parts[i];
-                 if ((rp->part->type == EDJE_PART_TYPE_GROUP || rp->part->type == EDJE_PART_TYPE_EXTERNAL) &&
-                     (rp->swallowed_object) &&
+                 if ((((rp->part->type == EDJE_PART_TYPE_GROUP
+                       || rp->part->type == EDJE_PART_TYPE_EXTERNAL)
+                      && (rp->swallowed_object))
+                     || rp->part->type == EDJE_PART_TYPE_BOX) &&
                      (rp->part) && (rp->part->name) &&
                      (strcmp(rp->part->name, part) == 0))
                    {
@@ -1054,7 +1066,37 @@ _edje_emit(Edje *ed, const char *sig, const char *src)
                           _edje_external_signal_emit(rp->swallowed_object, newsig, src);
                           return;
                        }
-                   }
+                     else if (rp->part->type == EDJE_PART_TYPE_BOX
+                              || rp->part->type == EDJE_PART_TYPE_TABLE)
+                       {
+                          const char *partid;
+                          Evas_Object *child;
+                          Eina_List *l;
+                          Edje *ed2 = NULL;
+                          Eina_Bool number = EINA_TRUE;
+                          unsigned int i;
+                          int id;
+
+                          idx = strchr(newsig, EDJE_PART_PATH_SEPARATOR_INDEXR);
+
+                          if (!idx) return ;
+                          if (idx[1] != ':') return ;
+                          if (!rp->object) return;
+
+                          partid = newsig;
+                          newsig = idx;
+
+                          *newsig = '\0';
+                          newsig++;
+
+                          child = _edje_children_get(rp, partid);
+
+                          if (child) ed2 = _edje_fetch(child);
+                          if (ed2) _edje_emit(ed2, newsig, src);
+
+                          return;
+                       }
+                  }
               }
          }
      }
index 21fd78c..90b77d6 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <string.h>
+#include <ctype.h>
 
 #include "edje_private.h"
 
@@ -4239,39 +4240,94 @@ _edje_real_part_recursive_get(Edje *ed, const char *part)
    return rp;
 }
 
+Evas_Object *
+_edje_children_get(Edje_Real_Part *rp, const char *partid)
+{
+   Evas_Object *child;
+   Eina_List *l;
+   Eina_Bool number = EINA_TRUE;
+   unsigned int i;
+
+   fprintf(stderr, "edje_children_get\n");
+
+   for (i = 0; i < strlen(partid); ++i)
+     number &= isdigit(partid[i]) ? EINA_TRUE : EINA_FALSE;
+
+   if (rp->part->type == EDJE_PART_TYPE_BOX)
+     l = evas_object_box_children_get(rp->object);
+   else
+     if (rp->part->type == EDJE_PART_TYPE_TABLE)
+       l = evas_object_table_children_get(rp->object);
+     else
+       return NULL;
+
+   if (number)
+     {
+       child = eina_list_nth(l, atoi(partid));
+       eina_list_free(l);
+     }
+   else
+     {
+       EINA_LIST_FREE(l, child)
+         if (!strcmp(evas_object_name_get(child), partid))
+           break ;
+       eina_list_free(l);
+     }
+
+   return child;
+}
+
 Edje_Real_Part *
 _edje_real_part_recursive_get_helper(Edje *ed, char **path)
 {
    Edje_Real_Part *rp;
-   Evas_Object *o;
-   Eina_List *l;
+   Evas_Object *child;
+   char *idx = NULL;
 
    //printf("  lookup: %s on %s\n", path[0], ed->parent ? ed->parent : "-");
+   if (path[0])
+     idx = strchr(path[0], EDJE_PART_PATH_SEPARATOR_INDEXL);
+   if (idx)
+     {
+       char *end;
+
+       fprintf(stderr, "looking for [] in `%s`\n", path[0]);
+       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 (path[1] == NULL) return rp;
-
    if (!rp) return NULL;
+
    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++;
-       return _edje_real_part_recursive_get_helper(ed, path);
-      case EDJE_PART_TYPE_BOX: case EDJE_PART_TYPE_TABLE:
-       if (!rp->items) return NULL;
-       path++;
-       EINA_LIST_FOREACH(rp->items, l, o)
-          {
-             ed = _edje_fetch(o);
-             if (!ed) return NULL;
-             if ((rp = _edje_real_part_recursive_get_helper(ed, path)))
-               return rp;
-          }
-       return NULL;
+        if (!rp->swallowed_object) return NULL;
+        ed = _edje_fetch(rp->swallowed_object);
+        if (!ed) return NULL;
+        path++;
+        return _edje_real_part_recursive_get_helper(ed, path);
+      case EDJE_PART_TYPE_BOX:
+      case EDJE_PART_TYPE_TABLE:
+        if (!idx) return rp;
+        path++;
+
+        child = _edje_children_get(rp, idx);
+
+        ed = _edje_fetch(child);
+        if (!ed) return NULL;
+        if ((rp = _edje_real_part_recursive_get_helper(ed, path)))
+          return rp;
+
+        return NULL;
       default:
-       return NULL;
+        return NULL;
      }
 }