elm_layout.c: refactoring. moved code around for better readability like other eo...
authorDaniel Juyung Seo <seojuyung2@gmail.com>
Thu, 29 Aug 2013 07:39:20 +0000 (16:39 +0900)
committerDaniel Juyung Seo <seojuyung2@gmail.com>
Thu, 29 Aug 2013 07:39:20 +0000 (16:39 +0900)
src/lib/elm_layout.c

index 41d5fbb..597aa15 100644 (file)
@@ -77,21 +77,6 @@ _elm_layout_smart_translate(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
    if (ret) *ret = EINA_TRUE;
 }
 
-/* layout's sizing evaluation is deferred. evaluation requests are
- * queued up and only flag the object as 'changed'. when it comes to
- * Evas's rendering phase, it will be addressed, finally (see
- * _elm_layout_smart_calculate()). */
-static void
-_elm_layout_smart_sizing_eval(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
-{
-   Elm_Layout_Smart_Data *sd = _pd;
-
-   if (sd->needs_size_calc) return;
-   sd->needs_size_calc = EINA_TRUE;
-
-   evas_object_smart_changed(obj);
-}
-
 static void
 _on_sub_object_size_hint_change(void *data,
                                 Evas *e __UNUSED__,
@@ -548,17 +533,6 @@ _elm_layout_smart_focus_direction(Eo *obj, void *_pd, va_list *list)
 }
 
 static void
-_elm_layout_smart_signal_emit(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
-{
-   const char *emission = va_arg(*list, const char *);
-   const char *source = va_arg(*list, const char *);
-
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
-
-   edje_object_signal_emit(wd->resize_obj, emission, source);
-}
-
-static void
 _edje_signal_callback(void *data,
                       Evas_Object *obj __UNUSED__,
                       const char *emission,
@@ -570,72 +544,6 @@ _edje_signal_callback(void *data,
 }
 
 static void
-_elm_layout_smart_signal_callback_add(Eo *obj, void *_pd, va_list *list)
-{
-   const char *emission = va_arg(*list, const char *);
-   const char *source = va_arg(*list, const char *);
-   Edje_Signal_Cb func_cb = va_arg(*list, Edje_Signal_Cb);
-   void *data = va_arg(*list, void *);
-
-   Edje_Signal_Data *esd;
-
-   Elm_Layout_Smart_Data *sd = _pd;
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
-
-   esd = ELM_NEW(Edje_Signal_Data);
-   if (!esd) return;
-
-   esd->obj = obj;
-   esd->func = func_cb;
-   esd->emission = eina_stringshare_add(emission);
-   esd->source = eina_stringshare_add(source);
-   esd->data = data;
-   sd->edje_signals = eina_list_append(sd->edje_signals, esd);
-
-   edje_object_signal_callback_add
-     (wd->resize_obj, emission, source,
-     _edje_signal_callback, esd);
-}
-
-static void
-_elm_layout_smart_signal_callback_del(Eo *obj, void *_pd, va_list *list)
-{
-   Edje_Signal_Data *esd = NULL;
-   void *data = NULL;
-   Eina_List *l;
-
-   const char *emission = va_arg(*list, const char *);
-   const char *source = va_arg(*list, const char *);
-   Edje_Signal_Cb func_cb = va_arg(*list, Edje_Signal_Cb);
-   void **ret = va_arg(*list, void **);
-   if (ret) *ret = NULL;
-
-   Elm_Layout_Smart_Data *sd = _pd;
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
-
-   EINA_LIST_FOREACH(sd->edje_signals, l, esd)
-     {
-        if ((esd->func == func_cb) && (!strcmp(esd->emission, emission)) &&
-            (!strcmp(esd->source, source)))
-          {
-             sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
-             eina_stringshare_del(esd->emission);
-             eina_stringshare_del(esd->source);
-             data = esd->data;
-
-             edje_object_signal_callback_del_full
-               (wd->resize_obj, emission, source,
-               _edje_signal_callback, esd);
-
-             free(esd);
-
-             if (ret) *ret = data;
-             return; /* stop at 1st match */
-          }
-     }
-}
-
-static void
 _elm_layout_smart_text_aliases_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list)
 {
    const Elm_Layout_Part_Alias_Description **aliases = va_arg(*list, const Elm_Layout_Part_Alias_Description **);
@@ -702,958 +610,810 @@ _elm_layout_part_aliasing_eval(const Evas_Object *obj EINA_UNUSED,
 }
 
 static void
-_elm_layout_smart_text_set(Eo *obj, void *_pd, va_list *list)
+_box_reference_del(void *data,
+                   Evas *e __UNUSED__,
+                   Evas_Object *obj __UNUSED__,
+                   void *event_info __UNUSED__)
 {
-   Elm_Layout_Smart_Data *sd = _pd;
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+   Elm_Layout_Sub_Object_Data *sub_d = data;
+   sub_d->p.box.reference = NULL;
+}
 
-   const char *part = va_arg(*list, const char *);
-   const char *text = va_arg(*list, const char *);
-   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
+static Evas_Object *
+_sub_box_remove(Evas_Object *obj,
+                Elm_Layout_Smart_Data *sd,
+                Elm_Layout_Sub_Object_Data *sub_d)
+{
+   Evas_Object *child = sub_d->obj; /* sub_d will die in
+                                     * _elm_layout_smart_sub_object_del */
 
-   Eina_List *l;
-   Elm_Layout_Sub_Object_Data *sub_d = NULL;
+   if (sub_d->type == BOX_INSERT_BEFORE)
+     evas_object_event_callback_del_full
+       ((Evas_Object *)sub_d->p.box.reference,
+       EVAS_CALLBACK_DEL, _box_reference_del, sub_d);
 
-   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_TRUE))
-     return;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(sd->obj, ELM_OBJ_WIDGET_CLASS);
+   edje_object_part_box_remove
+     (wd->resize_obj, sub_d->part, child);
 
-   EINA_LIST_FOREACH(sd->subs, l, sub_d)
+   if (!elm_widget_sub_object_del(obj, child))
      {
-        if ((sub_d->type == TEXT) && (!strcmp(part, sub_d->part)))
-          {
-             if (!text)
-               {
-                  eina_stringshare_del(sub_d->part);
-                  eina_stringshare_del(sub_d->p.text.text);
-                  free(sub_d);
-                  edje_object_part_text_escaped_set
-                    (wd->resize_obj, part, NULL);
-                  sd->subs = eina_list_remove_list(sd->subs, l);
-                  goto end;
-               }
-             else
-               break;
-          }
-        sub_d = NULL;
+        ERR("could not remove sub object %p from %p", child, obj);
+        return NULL;
      }
 
-   if (!edje_object_part_text_escaped_set
-         (wd->resize_obj, part, text))
-     return;
+   return child;
+}
 
-   if (!sub_d)
+static Eina_Bool
+_sub_box_is(const Elm_Layout_Sub_Object_Data *sub_d)
+{
+   switch (sub_d->type)
      {
-        sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
-        if (!sub_d) return;
-        sub_d->type = TEXT;
-        sub_d->part = eina_stringshare_add(part);
-        sd->subs = eina_list_append(sd->subs, sub_d);
+      case BOX_APPEND:
+      case BOX_PREPEND:
+      case BOX_INSERT_BEFORE:
+      case BOX_INSERT_AT:
+        return EINA_TRUE;
+
+      default:
+        return EINA_FALSE;
      }
+}
 
-   eina_stringshare_replace(&sub_d->p.text.text, text);
+static Evas_Object *
+_sub_table_remove(Evas_Object *obj,
+                  Elm_Layout_Smart_Data *sd,
+                  Elm_Layout_Sub_Object_Data *sub_d)
+{
+   Evas_Object *child;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(sd->obj, ELM_OBJ_WIDGET_CLASS);
 
-   _text_signal_emit(sd, sub_d, !!text);
+   child = sub_d->obj; /* sub_d will die in _elm_layout_smart_sub_object_del */
 
-   if (!wd->frozen)
-     eo_do(obj, elm_obj_layout_sizing_eval());
+   edje_object_part_table_unpack
+     (wd->resize_obj, sub_d->part, child);
 
-   if (_elm_config->access_mode == ELM_ACCESS_MODE_ON &&
-       wd->can_access && !(sub_d->obj))
-     sub_d->obj = _elm_access_edje_object_part_object_register
-         (obj, elm_layout_edje_get(obj), part);
+   if (!elm_widget_sub_object_del(obj, child))
+     {
+        ERR("could not remove sub object %p from %p", child, obj);
+        return NULL;
+     }
 
-end:
-   if (ret) *ret = EINA_TRUE;
+   return child;
 }
 
 static void
-_elm_layout_smart_text_get(Eo *obj, void *_pd, va_list *list)
+_on_size_evaluate_signal(void *data,
+                         Evas_Object *obj __UNUSED__,
+                         const char *emission __UNUSED__,
+                         const char *source __UNUSED__)
 {
-   Elm_Layout_Smart_Data *sd = _pd;
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+   eo_do(data, elm_obj_layout_sizing_eval());
+}
 
-   const char *part = va_arg(*list, const char *);
-   const char **text = va_arg(*list, const char **);
-   *text = NULL;
+static void
+_elm_layout_smart_add(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+   Evas_Object *edje;
 
-   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_TRUE))
-     return;
+   elm_widget_sub_object_add(eo_parent_get(obj), obj);
 
-   *text = edje_object_part_text_get(wd->resize_obj, part);
+   /* has to be there *before* parent's smart_add() */
+   edje = edje_object_add(evas_object_evas_get(obj));
+   elm_widget_resize_object_set(obj, edje);
+
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
+
+   elm_widget_can_focus_set(obj, EINA_FALSE);
+
+   edje_object_signal_callback_add
+     (edje, "size,eval", "elm", _on_size_evaluate_signal, obj);
+
+   eo_do(obj, elm_obj_layout_sizing_eval());
 }
 
 static void
-_elm_layout_smart_content_set(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
 {
    Elm_Layout_Sub_Object_Data *sub_d;
-   const Eina_List *l;
-
-   const char *part = va_arg(*list, const char *);
-   Evas_Object *content = va_arg(*list, Evas_Object *);
-   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
+   Elm_Layout_Sub_Object_Cursor *pc;
+   Edje_Signal_Data *esd;
+   Evas_Object *child;
+   Eina_List *l;
 
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_FALSE))
-     return;
+   elm_layout_freeze(obj);
 
-   EINA_LIST_FOREACH(sd->subs, l, sub_d)
+   EINA_LIST_FREE(sd->subs, sub_d)
      {
-        if (sub_d->type == SWALLOW)
-          {
-             if (!strcmp(part, sub_d->part))
-               {
-                  if (content == sub_d->obj) goto end;
-                  evas_object_del(sub_d->obj);
-                  break;
-               }
-             /* was previously swallowed at another part -- mimic
-              * edje_object_part_swallow()'s behavior, then */
-             else if (content == sub_d->obj)
-               {
-                  elm_widget_sub_object_del(obj, content);
-                  break;
-               }
-          }
-     }
+        eina_stringshare_del(sub_d->part);
 
-   if (content)
-     {
-        if (!elm_widget_sub_object_add(obj, content))
-          return;
+        if (sub_d->type == TEXT)
+          eina_stringshare_del(sub_d->p.text.text);
 
-        if (!edje_object_part_swallow
-              (wd->resize_obj, part, content))
-          {
-             ERR("could not swallow %p into part '%s'", content, part);
-             return;
-          }
+        free(sub_d);
+     }
 
-        sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
-        sub_d->type = SWALLOW;
-        sub_d->part = eina_stringshare_add(part);
-        sub_d->obj = content;
-        sd->subs = eina_list_append(sd->subs, sub_d);
+   EINA_LIST_FREE(sd->parts_cursors, pc)
+     _part_cursor_free(pc);
 
-        _icon_signal_emit(sd, sub_d, EINA_TRUE);
+   EINA_LIST_FREE(sd->edje_signals, esd)
+     {
+        eina_stringshare_del(esd->emission);
+        eina_stringshare_del(esd->source);
+        free(esd);
      }
 
-   if (wd->frozen) goto end;
+   eina_stringshare_del(sd->klass);
+   eina_stringshare_del(sd->group);
 
-   eo_do(obj, elm_obj_layout_sizing_eval());
+   /* let's make our Edje object the *last* to be processed, since it
+    * may (smart) parent other sub objects here */
+   EINA_LIST_FOREACH(wd->subobjs, l, child)
+     {
+        if (child == wd->resize_obj)
+          {
+             wd->subobjs =
+               eina_list_demote_list(wd->subobjs, l);
+             break;
+          }
+     }
 
-end:
-   if (ret) *ret = EINA_TRUE;
+   eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
 }
 
+/* rewrite or extend this one on your derived class as to suit your
+ * needs */
 static void
-_elm_layout_smart_content_get(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_calculate(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
 {
-   const Eina_List *l;
-   Elm_Layout_Sub_Object_Data *sub_d;
-
-   const char *part = va_arg(*list, const char *);
-   Evas_Object **content = va_arg(*list, Evas_Object **);
-   *content = NULL;
-
    Elm_Layout_Smart_Data *sd = _pd;
 
-   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_FALSE))
-     return;
-
-   EINA_LIST_FOREACH(sd->subs, l, sub_d)
+   if (sd->needs_size_calc)
      {
-        if ((sub_d->type == SWALLOW) && !strcmp(part, sub_d->part))
-          {
-             *content = sub_d->obj;
-             return;
-          }
+        _sizing_eval(obj, sd);
+        sd->needs_size_calc = EINA_FALSE;
      }
 }
 
-static void
-_elm_layout_smart_content_unset(Eo *obj, void *_pd, va_list *list)
+static Elm_Layout_Sub_Object_Cursor *
+_parts_cursors_find(Elm_Layout_Smart_Data *sd,
+                    const char *part)
 {
-   Elm_Layout_Sub_Object_Data *sub_d;
    const Eina_List *l;
+   Elm_Layout_Sub_Object_Cursor *pc;
 
-   const char *part = va_arg(*list, const char *);
-   Evas_Object **ret = va_arg(*list, Evas_Object **);
-   if (ret) *ret = NULL;
-
-   Elm_Layout_Smart_Data *sd = _pd;
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
-
-   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_FALSE))
-     return;
-
-   EINA_LIST_FOREACH(sd->subs, l, sub_d)
+   EINA_LIST_FOREACH(sd->parts_cursors, l, pc)
      {
-        if ((sub_d->type == SWALLOW) && (!strcmp(part, sub_d->part)))
-          {
-             Evas_Object *content;
-
-             if (!sub_d->obj) return;
+        if (!strcmp(pc->part, part))
+          return pc;
+     }
 
-             content = sub_d->obj; /* sub_d will die in
-                                    * _elm_layout_smart_sub_object_del */
+   return NULL;
+}
 
-             if (!elm_widget_sub_object_del(obj, content))
-               {
-                  ERR("could not remove sub object %p from %p", content, obj);
-                  return;
-               }
+/* The public functions down here are meant to operate on whichever
+ * widget inheriting from elm_layout */
 
-             edje_object_part_unswallow
-               (wd->resize_obj, content);
-             if (ret) *ret = content;
-             return;
-          }
-     }
+EAPI Eina_Bool
+elm_layout_file_set(Evas_Object *obj,
+                    const char *file,
+                    const char *group)
+{
+   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
+   Eina_Bool ret = EINA_FALSE;
+   eo_do(obj, elm_obj_layout_file_set(file, group, &ret));
+   return ret;
 }
 
 static void
-_elm_layout_smart_box_append(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_file_set(Eo *obj, void *_pd, va_list *list)
 {
-   Elm_Layout_Sub_Object_Data *sub_d;
-
-   const char *part = va_arg(*list, const char *);
-   Evas_Object *child = va_arg(*list, Evas_Object *);
+   const char *file = va_arg(*list, const char *);
+   const char *group = va_arg(*list, const char *);
    Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
+   Eina_Bool int_ret = EINA_FALSE;
 
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   if (!edje_object_part_box_append
-         (wd->resize_obj, part, child))
-     {
-        ERR("child %p could not be appended to box part '%s'", child, part);
-        return;
-     }
-
-   if (!elm_widget_sub_object_add(obj, child))
-     {
-        edje_object_part_box_remove
-          (wd->resize_obj, part, child);
-        return;
-     }
+   int_ret =
+     edje_object_file_set(wd->resize_obj, file, group);
 
-   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
-   sub_d->type = BOX_APPEND;
-   sub_d->part = eina_stringshare_add(part);
-   sub_d->obj = child;
-   sd->subs = eina_list_append(sd->subs, sub_d);
+   if (int_ret) _visuals_refresh(obj, sd);
+   else
+     ERR("failed to set edje file '%s', group '%s': %s",
+         file, group,
+         edje_load_error_str
+           (edje_object_load_error_get(wd->resize_obj)));
 
-   if (wd->frozen) goto end;
-   eo_do(obj, elm_obj_layout_sizing_eval());
+   if (ret) *ret = int_ret;
+}
 
-end:
-   if (ret) *ret = EINA_TRUE;
+EAPI Eina_Bool
+elm_layout_theme_set(Evas_Object *obj,
+                     const char *klass,
+                     const char *group,
+                     const char *style)
+{
+   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
+   Eina_Bool ret = EINA_FALSE;
+   eo_do(obj, elm_obj_layout_theme_set(klass, group, style, &ret));
+   return ret;
 }
 
 static void
-_elm_layout_smart_box_prepend(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_theme_set(Eo *obj, void *_pd, va_list *list)
 {
-   Elm_Layout_Sub_Object_Data *sub_d;
-
-   const char *part = va_arg(*list, const char *);
-   Evas_Object *child = va_arg(*list, Evas_Object *);
+   const char *klass = va_arg(*list, const char *);
+   const char *group = va_arg(*list, const char *);
+   const char *style = va_arg(*list, const char *);
    Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
+   Eina_Bool int_ret = EINA_FALSE;
 
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   if (!edje_object_part_box_prepend
-         (wd->resize_obj, part, child))
-     {
-        ERR("child %p could not be prepended to box part '%s'", child, part);
-        return;
-     }
-
-   if (!elm_widget_sub_object_add(obj, child))
-     {
-        edje_object_part_box_remove
-          (wd->resize_obj, part, child);
-        return;
-     }
-
-   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
-   sub_d->type = BOX_PREPEND;
-   sub_d->part = eina_stringshare_add(part);
-   sub_d->obj = child;
-   sd->subs = eina_list_prepend(sd->subs, sub_d);
+   eina_stringshare_replace(&(sd->klass), klass);
+   eina_stringshare_replace(&(sd->group), group);
+   eina_stringshare_replace(&(wd->style), style);
 
-   if (wd->frozen) goto end;;
-   eo_do(obj, elm_obj_layout_sizing_eval());
+   /* not issuing smart theme directly here, because one may want to
+      use this function inside a smart theme routine of its own */
+   int_ret = elm_widget_theme_object_set
+       (obj, wd->resize_obj, sd->klass, sd->group,
+       elm_widget_style_get(obj));
+   evas_object_smart_callback_call(obj, SIG_THEME_CHANGED, NULL);
 
-end:
-   if (ret) *ret = EINA_TRUE;
+   if (ret) *ret = int_ret;
 }
 
-static void
-_box_reference_del(void *data,
-                   Evas *e __UNUSED__,
-                   Evas_Object *obj __UNUSED__,
-                   void *event_info __UNUSED__)
+
+EAPI void
+elm_layout_signal_emit(Evas_Object *obj,
+                       const char *emission,
+                       const char *source)
 {
-   Elm_Layout_Sub_Object_Data *sub_d = data;
-   sub_d->p.box.reference = NULL;
+   ELM_LAYOUT_CHECK(obj);
+   eo_do(obj, elm_obj_layout_signal_emit(emission, source));
 }
 
 static void
-_elm_layout_smart_box_insert_before(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_signal_emit(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
 {
-   Elm_Layout_Sub_Object_Data *sub_d;
-
-   const char *part = va_arg(*list, const char *);
-   Evas_Object *child = va_arg(*list, Evas_Object *);
-   const Evas_Object *reference = va_arg(*list, const Evas_Object *);
-   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
+   const char *emission = va_arg(*list, const char *);
+   const char *source = va_arg(*list, const char *);
 
-   Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   if (!edje_object_part_box_insert_before
-         (wd->resize_obj, part, child, reference))
-     {
-        ERR("child %p could not be inserted before %p inf box part '%s'",
-            child, reference, part);
-        return;
-     }
-
-   if (!elm_widget_sub_object_add(obj, child))
-     {
-        edje_object_part_box_remove
-          (wd->resize_obj, part, child);
-        return;
-     }
-
-   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
-   sub_d->type = BOX_INSERT_BEFORE;
-   sub_d->part = eina_stringshare_add(part);
-   sub_d->obj = child;
-   sub_d->p.box.reference = reference;
-   sd->subs = eina_list_append(sd->subs, sub_d);
-
-   evas_object_event_callback_add
-     ((Evas_Object *)reference, EVAS_CALLBACK_DEL, _box_reference_del, sub_d);
-
-   if (wd->frozen) goto end;
-   eo_do(obj, elm_obj_layout_sizing_eval());
+   edje_object_signal_emit(wd->resize_obj, emission, source);
+}
 
-end:
-   if (ret) *ret = EINA_TRUE;
+EAPI void
+elm_layout_signal_callback_add(Evas_Object *obj,
+                               const char *emission,
+                               const char *source,
+                               Edje_Signal_Cb func,
+                               void *data)
+{
+   ELM_LAYOUT_CHECK(obj);
+   eo_do(obj, elm_obj_layout_signal_callback_add(emission, source, func, data));
 }
 
 static void
-_elm_layout_smart_box_insert_at(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_signal_callback_add(Eo *obj, void *_pd, va_list *list)
 {
-   Elm_Layout_Sub_Object_Data *sub_d;
+   const char *emission = va_arg(*list, const char *);
+   const char *source = va_arg(*list, const char *);
+   Edje_Signal_Cb func_cb = va_arg(*list, Edje_Signal_Cb);
+   void *data = va_arg(*list, void *);
 
-   const char *part = va_arg(*list, const char *);
-   Evas_Object *child = va_arg(*list, Evas_Object *);
-   unsigned int pos = va_arg(*list, unsigned int);
-   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
+   Edje_Signal_Data *esd;
 
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   if (!edje_object_part_box_insert_at
-         (wd->resize_obj, part, child, pos))
-     {
-        ERR("child %p could not be inserted at %u to box part '%s'",
-            child, pos, part);
-        return;
-     }
-
-   if (!elm_widget_sub_object_add(obj, child))
-     {
-        edje_object_part_box_remove
-          (wd->resize_obj, part, child);
-        return;
-     }
-
-   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
-   sub_d->type = BOX_INSERT_AT;
-   sub_d->part = eina_stringshare_add(part);
-   sub_d->obj = child;
-   sub_d->p.box.pos = pos;
-   sd->subs = eina_list_append(sd->subs, sub_d);
-
-   if (wd->frozen) goto end;
-   eo_do(obj, elm_obj_layout_sizing_eval());
-
-end:
-   if (ret) *ret = EINA_TRUE;
-}
-
-static Evas_Object *
-_sub_box_remove(Evas_Object *obj,
-                Elm_Layout_Smart_Data *sd,
-                Elm_Layout_Sub_Object_Data *sub_d)
-{
-   Evas_Object *child = sub_d->obj; /* sub_d will die in
-                                     * _elm_layout_smart_sub_object_del */
-
-   if (sub_d->type == BOX_INSERT_BEFORE)
-     evas_object_event_callback_del_full
-       ((Evas_Object *)sub_d->p.box.reference,
-       EVAS_CALLBACK_DEL, _box_reference_del, sub_d);
-
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(sd->obj, ELM_OBJ_WIDGET_CLASS);
-   edje_object_part_box_remove
-     (wd->resize_obj, sub_d->part, child);
+   esd = ELM_NEW(Edje_Signal_Data);
+   if (!esd) return;
 
-   if (!elm_widget_sub_object_del(obj, child))
-     {
-        ERR("could not remove sub object %p from %p", child, obj);
-        return NULL;
-     }
+   esd->obj = obj;
+   esd->func = func_cb;
+   esd->emission = eina_stringshare_add(emission);
+   esd->source = eina_stringshare_add(source);
+   esd->data = data;
+   sd->edje_signals = eina_list_append(sd->edje_signals, esd);
 
-   return child;
+   edje_object_signal_callback_add
+     (wd->resize_obj, emission, source,
+     _edje_signal_callback, esd);
 }
 
-static Eina_Bool
-_sub_box_is(const Elm_Layout_Sub_Object_Data *sub_d)
+EAPI void *
+elm_layout_signal_callback_del(Evas_Object *obj,
+                               const char *emission,
+                               const char *source,
+                               Edje_Signal_Cb func)
 {
-   switch (sub_d->type)
-     {
-      case BOX_APPEND:
-      case BOX_PREPEND:
-      case BOX_INSERT_BEFORE:
-      case BOX_INSERT_AT:
-        return EINA_TRUE;
-
-      default:
-        return EINA_FALSE;
-     }
+   ELM_LAYOUT_CHECK(obj) NULL;
+   void *ret = NULL;
+   eo_do(obj, elm_obj_layout_signal_callback_del(emission, source, func, &ret));
+   return ret;
 }
 
 static void
-_elm_layout_smart_box_remove(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_signal_callback_del(Eo *obj, void *_pd, va_list *list)
 {
+   Edje_Signal_Data *esd = NULL;
+   void *data = NULL;
+   Eina_List *l;
 
-   const char *part = va_arg(*list, const char *);
-   Evas_Object *child = va_arg(*list, Evas_Object *);
-   Evas_Object **ret = va_arg(*list, Evas_Object **);
+   const char *emission = va_arg(*list, const char *);
+   const char *source = va_arg(*list, const char *);
+   Edje_Signal_Cb func_cb = va_arg(*list, Edje_Signal_Cb);
+   void **ret = va_arg(*list, void **);
    if (ret) *ret = NULL;
-   Evas_Object *int_ret = NULL;
-
-   EINA_SAFETY_ON_NULL_RETURN(part);
-   EINA_SAFETY_ON_NULL_RETURN(child);
 
    Elm_Layout_Smart_Data *sd = _pd;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   const Eina_List *l;
-   Elm_Layout_Sub_Object_Data *sub_d;
-
-   EINA_LIST_FOREACH(sd->subs, l, sub_d)
+   EINA_LIST_FOREACH(sd->edje_signals, l, esd)
      {
-        if (!_sub_box_is(sub_d)) continue;
-        if ((sub_d->obj == child) && (!strcmp(sub_d->part, part)))
+        if ((esd->func == func_cb) && (!strcmp(esd->emission, emission)) &&
+            (!strcmp(esd->source, source)))
           {
-             int_ret = _sub_box_remove(obj, sd, sub_d);
-             if (ret) *ret = int_ret;
-             return;
-          }
-     }
-}
-
-static void
-_elm_layout_smart_box_remove_all(Eo *obj, void *_pd, va_list *list)
-{
-   const char *part = va_arg(*list, const char *);
-   Eina_Bool clear = va_arg(*list, int);
-   Eina_Bool *ret= va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
-
-   EINA_SAFETY_ON_NULL_RETURN(part);
+             sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
+             eina_stringshare_del(esd->emission);
+             eina_stringshare_del(esd->source);
+             data = esd->data;
 
-   Elm_Layout_Smart_Data *sd = _pd;
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+             edje_object_signal_callback_del_full
+               (wd->resize_obj, emission, source,
+               _edje_signal_callback, esd);
 
-   Elm_Layout_Sub_Object_Data *sub_d;
-   Eina_List *lst;
+             free(esd);
 
-   lst = eina_list_clone(sd->subs);
-   EINA_LIST_FREE(lst, sub_d)
-     {
-        if (!_sub_box_is(sub_d)) continue;
-        if (!strcmp(sub_d->part, part))
-          {
-             /* original item's deletion handled at sub-obj-del */
-             Evas_Object *child = _sub_box_remove(obj, sd, sub_d);
-             if ((clear) && (child)) evas_object_del(child);
+             if (ret) *ret = data;
+             return; /* stop at 1st match */
           }
      }
+}
 
-   /* eventually something may not be added with elm_layout, delete them
-    * as well */
-   edje_object_part_box_remove_all
-     (wd->resize_obj, part, clear);
-
-   if (ret) *ret = EINA_TRUE;
+EAPI Eina_Bool
+elm_layout_content_set(Evas_Object *obj,
+                       const char *swallow,
+                       Evas_Object *content)
+{
+   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
+   Eina_Bool ret = EINA_FALSE;
+   eo_do(obj, elm_obj_container_content_set(swallow, content, &ret));
+   return ret;
 }
 
 static void
-_elm_layout_smart_table_pack(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_content_set(Eo *obj, void *_pd, va_list *list)
 {
    Elm_Layout_Sub_Object_Data *sub_d;
+   const Eina_List *l;
 
    const char *part = va_arg(*list, const char *);
-   Evas_Object *child = va_arg(*list, Evas_Object *);
-   unsigned short col = va_arg(*list, unsigned int);
-   unsigned short row = va_arg(*list, unsigned int);
-   unsigned short colspan = va_arg(*list, unsigned int);
-   unsigned short rowspan = va_arg(*list, unsigned int);
+   Evas_Object *content = va_arg(*list, Evas_Object *);
    Eina_Bool *ret = va_arg(*list, Eina_Bool *);
    if (ret) *ret = EINA_FALSE;
 
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   if (!edje_object_part_table_pack
-         (wd->resize_obj, part, child, col,
-         row, colspan, rowspan))
+   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_FALSE))
+     return;
+
+   EINA_LIST_FOREACH(sd->subs, l, sub_d)
      {
-        ERR("child %p could not be packed into box part '%s' col=%uh, row=%hu,"
-            " colspan=%hu, rowspan=%hu", child, part, col, row, colspan,
-            rowspan);
-        return;
+        if (sub_d->type == SWALLOW)
+          {
+             if (!strcmp(part, sub_d->part))
+               {
+                  if (content == sub_d->obj) goto end;
+                  evas_object_del(sub_d->obj);
+                  break;
+               }
+             /* was previously swallowed at another part -- mimic
+              * edje_object_part_swallow()'s behavior, then */
+             else if (content == sub_d->obj)
+               {
+                  elm_widget_sub_object_del(obj, content);
+                  break;
+               }
+          }
      }
 
-   if (!elm_widget_sub_object_add(obj, child))
+   if (content)
      {
-        edje_object_part_table_unpack
-          (wd->resize_obj, part, child);
-        return;
-     }
+        if (!elm_widget_sub_object_add(obj, content))
+          return;
 
-   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
-   sub_d->type = TABLE_PACK;
-   sub_d->part = eina_stringshare_add(part);
-   sub_d->obj = child;
-   sub_d->p.table.col = col;
-   sub_d->p.table.row = row;
-   sub_d->p.table.colspan = colspan;
-   sub_d->p.table.rowspan = rowspan;
-   sd->subs = eina_list_append(sd->subs, sub_d);
+        if (!edje_object_part_swallow
+              (wd->resize_obj, part, content))
+          {
+             ERR("could not swallow %p into part '%s'", content, part);
+             return;
+          }
+
+        sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
+        sub_d->type = SWALLOW;
+        sub_d->part = eina_stringshare_add(part);
+        sub_d->obj = content;
+        sd->subs = eina_list_append(sd->subs, sub_d);
+
+        _icon_signal_emit(sd, sub_d, EINA_TRUE);
+     }
 
    if (wd->frozen) goto end;
+
    eo_do(obj, elm_obj_layout_sizing_eval());
 
 end:
    if (ret) *ret = EINA_TRUE;
 }
 
-static Evas_Object *
-_sub_table_remove(Evas_Object *obj,
-                  Elm_Layout_Smart_Data *sd,
-                  Elm_Layout_Sub_Object_Data *sub_d)
+EAPI Evas_Object *
+elm_layout_content_get(const Evas_Object *obj,
+                       const char *swallow)
 {
-   Evas_Object *child;
-   Elm_Widget_Smart_Data *wd = eo_data_scope_get(sd->obj, ELM_OBJ_WIDGET_CLASS);
-
-   child = sub_d->obj; /* sub_d will die in _elm_layout_smart_sub_object_del */
-
-   edje_object_part_table_unpack
-     (wd->resize_obj, sub_d->part, child);
-
-   if (!elm_widget_sub_object_del(obj, child))
-     {
-        ERR("could not remove sub object %p from %p", child, obj);
-        return NULL;
-     }
-
-   return child;
+   ELM_LAYOUT_CHECK(obj) NULL;
+   Evas_Object *ret = NULL;
+   eo_do((Eo *) obj, elm_obj_container_content_get(swallow, &ret));
+   return ret;
 }
 
 static void
-_elm_layout_smart_table_unpack(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_content_get(Eo *obj, void *_pd, va_list *list)
 {
+   const Eina_List *l;
+   Elm_Layout_Sub_Object_Data *sub_d;
 
    const char *part = va_arg(*list, const char *);
-   Evas_Object *child = va_arg(*list, Evas_Object *);
-   Evas_Object **ret = va_arg(*list, Evas_Object **);
-   if (ret) *ret = NULL;
-   Evas_Object *int_ret = NULL;
-
-   EINA_SAFETY_ON_NULL_RETURN(part);
-   EINA_SAFETY_ON_NULL_RETURN(child);
+   Evas_Object **content = va_arg(*list, Evas_Object **);
+   *content = NULL;
 
    Elm_Layout_Smart_Data *sd = _pd;
 
-   const Eina_List *l;
-   Elm_Layout_Sub_Object_Data *sub_d;
+   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_FALSE))
+     return;
 
    EINA_LIST_FOREACH(sd->subs, l, sub_d)
      {
-        if (sub_d->type != TABLE_PACK) continue;
-        if ((sub_d->obj == child) && (!strcmp(sub_d->part, part)))
+        if ((sub_d->type == SWALLOW) && !strcmp(part, sub_d->part))
           {
-             int_ret = _sub_table_remove(obj, sd, sub_d);
-             if (ret) *ret = int_ret;
+             *content = sub_d->obj;
              return;
           }
      }
 }
 
+EAPI Evas_Object *
+elm_layout_content_unset(Evas_Object *obj,
+                         const char *swallow)
+{
+   ELM_LAYOUT_CHECK(obj) NULL;
+   Evas_Object *ret = NULL;
+   eo_do(obj, elm_obj_container_content_unset(swallow, &ret));
+   return ret;
+}
+
 static void
-_elm_layout_smart_table_clear(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_content_unset(Eo *obj, void *_pd, va_list *list)
 {
-   const char *part = va_arg(*list, const char *);
-   Eina_Bool clear = va_arg(*list, int);
-   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   if (ret) *ret = EINA_FALSE;
+   Elm_Layout_Sub_Object_Data *sub_d;
+   const Eina_List *l;
 
-   EINA_SAFETY_ON_NULL_RETURN(part);
+   const char *part = va_arg(*list, const char *);
+   Evas_Object **ret = va_arg(*list, Evas_Object **);
+   if (ret) *ret = NULL;
 
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   Elm_Layout_Sub_Object_Data *sub_d;
-   Eina_List *lst;
+   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_FALSE))
+     return;
 
-   lst = eina_list_clone(sd->subs);
-   EINA_LIST_FREE(lst, sub_d)
+   EINA_LIST_FOREACH(sd->subs, l, sub_d)
      {
-        if (sub_d->type != TABLE_PACK) continue;
-        if (!strcmp(sub_d->part, part))
+        if ((sub_d->type == SWALLOW) && (!strcmp(part, sub_d->part)))
           {
-             /* original item's deletion handled at sub-obj-del */
-             Evas_Object *child = _sub_table_remove(obj, sd, sub_d);
-             if ((clear) && (child)) evas_object_del(child);
-          }
-     }
+             Evas_Object *content;
 
-   /* eventually something may not be added with elm_layout, delete them
-    * as well */
-   edje_object_part_table_clear(wd->resize_obj, part, clear);
+             if (!sub_d->obj) return;
 
-   if (ret) *ret = EINA_TRUE;
-}
+             content = sub_d->obj; /* sub_d will die in
+                                    * _elm_layout_smart_sub_object_del */
 
-static void
-_on_size_evaluate_signal(void *data,
-                         Evas_Object *obj __UNUSED__,
-                         const char *emission __UNUSED__,
-                         const char *source __UNUSED__)
-{
-   eo_do(data, elm_obj_layout_sizing_eval());
+             if (!elm_widget_sub_object_del(obj, content))
+               {
+                  ERR("could not remove sub object %p from %p", content, obj);
+                  return;
+               }
+
+             edje_object_part_unswallow
+               (wd->resize_obj, content);
+             if (ret) *ret = content;
+             return;
+          }
+     }
 }
 
-static void
-_elm_layout_smart_add(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
+EAPI Eina_Bool
+elm_layout_text_set(Evas_Object *obj,
+                    const char *part,
+                    const char *text)
 {
-   Evas_Object *edje;
-
-   elm_widget_sub_object_add(eo_parent_get(obj), obj);
-
-   /* has to be there *before* parent's smart_add() */
-   edje = edje_object_add(evas_object_evas_get(obj));
-   elm_widget_resize_object_set(obj, edje);
-
-   eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
-
-   elm_widget_can_focus_set(obj, EINA_FALSE);
-
-   edje_object_signal_callback_add
-     (edje, "size,eval", "elm", _on_size_evaluate_signal, obj);
-
-   eo_do(obj, elm_obj_layout_sizing_eval());
+   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
+   Eina_Bool ret = EINA_FALSE;
+   text = elm_widget_part_text_translate(obj, part, text);
+   eo_do(obj, elm_obj_layout_text_set(part, text, &ret));
+   return ret;
 }
 
 static void
-_elm_layout_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
+_elm_layout_smart_text_set(Eo *obj, void *_pd, va_list *list)
 {
-   Elm_Layout_Sub_Object_Data *sub_d;
-   Elm_Layout_Sub_Object_Cursor *pc;
-   Edje_Signal_Data *esd;
-   Evas_Object *child;
-   Eina_List *l;
-
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   elm_layout_freeze(obj);
-
-   EINA_LIST_FREE(sd->subs, sub_d)
-     {
-        eina_stringshare_del(sub_d->part);
-
-        if (sub_d->type == TEXT)
-          eina_stringshare_del(sub_d->p.text.text);
-
-        free(sub_d);
-     }
-
-   EINA_LIST_FREE(sd->parts_cursors, pc)
-     _part_cursor_free(pc);
+   const char *part = va_arg(*list, const char *);
+   const char *text = va_arg(*list, const char *);
+   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+   if (ret) *ret = EINA_FALSE;
 
-   EINA_LIST_FREE(sd->edje_signals, esd)
-     {
-        eina_stringshare_del(esd->emission);
-        eina_stringshare_del(esd->source);
-        free(esd);
-     }
+   Eina_List *l;
+   Elm_Layout_Sub_Object_Data *sub_d = NULL;
 
-   eina_stringshare_del(sd->klass);
-   eina_stringshare_del(sd->group);
+   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_TRUE))
+     return;
 
-   /* let's make our Edje object the *last* to be processed, since it
-    * may (smart) parent other sub objects here */
-   EINA_LIST_FOREACH(wd->subobjs, l, child)
+   EINA_LIST_FOREACH(sd->subs, l, sub_d)
      {
-        if (child == wd->resize_obj)
+        if ((sub_d->type == TEXT) && (!strcmp(part, sub_d->part)))
           {
-             wd->subobjs =
-               eina_list_demote_list(wd->subobjs, l);
-             break;
+             if (!text)
+               {
+                  eina_stringshare_del(sub_d->part);
+                  eina_stringshare_del(sub_d->p.text.text);
+                  free(sub_d);
+                  edje_object_part_text_escaped_set
+                    (wd->resize_obj, part, NULL);
+                  sd->subs = eina_list_remove_list(sd->subs, l);
+                  goto end;
+               }
+             else
+               break;
           }
+        sub_d = NULL;
      }
 
-   eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
-}
-
-/* rewrite or extend this one on your derived class as to suit your
- * needs */
-static void
-_elm_layout_smart_calculate(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
-{
-   Elm_Layout_Smart_Data *sd = _pd;
+   if (!edje_object_part_text_escaped_set
+         (wd->resize_obj, part, text))
+     return;
 
-   if (sd->needs_size_calc)
+   if (!sub_d)
      {
-        _sizing_eval(obj, sd);
-        sd->needs_size_calc = EINA_FALSE;
+        sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
+        if (!sub_d) return;
+        sub_d->type = TEXT;
+        sub_d->part = eina_stringshare_add(part);
+        sd->subs = eina_list_append(sd->subs, sub_d);
      }
-}
 
-static Elm_Layout_Sub_Object_Cursor *
-_parts_cursors_find(Elm_Layout_Smart_Data *sd,
-                    const char *part)
-{
-   const Eina_List *l;
-   Elm_Layout_Sub_Object_Cursor *pc;
+   eina_stringshare_replace(&sub_d->p.text.text, text);
 
-   EINA_LIST_FOREACH(sd->parts_cursors, l, pc)
-     {
-        if (!strcmp(pc->part, part))
-          return pc;
-     }
+   _text_signal_emit(sd, sub_d, !!text);
 
-   return NULL;
-}
+   if (!wd->frozen)
+     eo_do(obj, elm_obj_layout_sizing_eval());
 
-/* The public functions down here are meant to operate on whichever
- * widget inheriting from elm_layout */
+   if (_elm_config->access_mode == ELM_ACCESS_MODE_ON &&
+       wd->can_access && !(sub_d->obj))
+     sub_d->obj = _elm_access_edje_object_part_object_register
+         (obj, elm_layout_edje_get(obj), part);
+
+end:
+   if (ret) *ret = EINA_TRUE;
+}
 
-EAPI Eina_Bool
-elm_layout_file_set(Evas_Object *obj,
-                    const char *file,
-                    const char *group)
+EAPI const char *
+elm_layout_text_get(const Evas_Object *obj,
+                    const char *part)
 {
-   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
-   Eina_Bool ret = EINA_FALSE;
-   eo_do(obj, elm_obj_layout_file_set(file, group, &ret));
+   ELM_LAYOUT_CHECK(obj) NULL;
+
+   const char *ret = NULL;
+   eo_do((Eo *) obj, elm_obj_layout_text_get(part, &ret));
    return ret;
 }
 
 static void
-_elm_layout_smart_file_set(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_text_get(Eo *obj, void *_pd, va_list *list)
 {
-   const char *file = va_arg(*list, const char *);
-   const char *group = va_arg(*list, const char *);
-   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   Eina_Bool int_ret = EINA_FALSE;
-
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   int_ret =
-     edje_object_file_set(wd->resize_obj, file, group);
+   const char *part = va_arg(*list, const char *);
+   const char **text = va_arg(*list, const char **);
+   *text = NULL;
 
-   if (int_ret) _visuals_refresh(obj, sd);
-   else
-     ERR("failed to set edje file '%s', group '%s': %s",
-         file, group,
-         edje_load_error_str
-           (edje_object_load_error_get(wd->resize_obj)));
+   if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_TRUE))
+     return;
 
-   if (ret) *ret = int_ret;
+   *text = edje_object_part_text_get(wd->resize_obj, part);
 }
 
 EAPI Eina_Bool
-elm_layout_theme_set(Evas_Object *obj,
-                     const char *klass,
-                     const char *group,
-                     const char *style)
+elm_layout_box_append(Evas_Object *obj,
+                      const char *part,
+                      Evas_Object *child)
 {
    ELM_LAYOUT_CHECK(obj) EINA_FALSE;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE);
+
    Eina_Bool ret = EINA_FALSE;
-   eo_do(obj, elm_obj_layout_theme_set(klass, group, style, &ret));
+   eo_do(obj, elm_obj_layout_box_append(part, child, &ret));
    return ret;
 }
 
 static void
-_elm_layout_smart_theme_set(Eo *obj, void *_pd, va_list *list)
+_elm_layout_smart_box_append(Eo *obj, void *_pd, va_list *list)
 {
-   const char *klass = va_arg(*list, const char *);
-   const char *group = va_arg(*list, const char *);
-   const char *style = va_arg(*list, const char *);
+   Elm_Layout_Sub_Object_Data *sub_d;
+
+   const char *part = va_arg(*list, const char *);
+   Evas_Object *child = va_arg(*list, Evas_Object *);
    Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-   Eina_Bool int_ret = EINA_FALSE;
+   if (ret) *ret = EINA_FALSE;
 
    Elm_Layout_Smart_Data *sd = _pd;
    Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-   eina_stringshare_replace(&(sd->klass), klass);
-   eina_stringshare_replace(&(sd->group), group);
-   eina_stringshare_replace(&(wd->style), style);
-
-   /* not issuing smart theme directly here, because one may want to
-      use this function inside a smart theme routine of its own */
-   int_ret = elm_widget_theme_object_set
-       (obj, wd->resize_obj, sd->klass, sd->group,
-       elm_widget_style_get(obj));
-   evas_object_smart_callback_call(obj, SIG_THEME_CHANGED, NULL);
-
-   if (ret) *ret = int_ret;
-}
+   if (!edje_object_part_box_append
+         (wd->resize_obj, part, child))
+     {
+        ERR("child %p could not be appended to box part '%s'", child, part);
+        return;
+     }
 
+   if (!elm_widget_sub_object_add(obj, child))
+     {
+        edje_object_part_box_remove
+          (wd->resize_obj, part, child);
+        return;
+     }
 
-EAPI void
-elm_layout_signal_emit(Evas_Object *obj,
-                       const char *emission,
-                       const char *source)
-{
-   ELM_LAYOUT_CHECK(obj);
-   eo_do(obj, elm_obj_layout_signal_emit(emission, source));
-}
+   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
+   sub_d->type = BOX_APPEND;
+   sub_d->part = eina_stringshare_add(part);
+   sub_d->obj = child;
+   sd->subs = eina_list_append(sd->subs, sub_d);
 
-EAPI void
-elm_layout_signal_callback_add(Evas_Object *obj,
-                               const char *emission,
-                               const char *source,
-                               Edje_Signal_Cb func,
-                               void *data)
-{
-   ELM_LAYOUT_CHECK(obj);
-   eo_do(obj, elm_obj_layout_signal_callback_add(emission, source, func, data));
-}
+   if (wd->frozen) goto end;
+   eo_do(obj, elm_obj_layout_sizing_eval());
 
-EAPI void *
-elm_layout_signal_callback_del(Evas_Object *obj,
-                               const char *emission,
-                               const char *source,
-                               Edje_Signal_Cb func)
-{
-   ELM_LAYOUT_CHECK(obj) NULL;
-   void *ret = NULL;
-   eo_do(obj, elm_obj_layout_signal_callback_del(emission, source, func, &ret));
-   return ret;
+end:
+   if (ret) *ret = EINA_TRUE;
 }
 
 EAPI Eina_Bool
-elm_layout_content_set(Evas_Object *obj,
-                       const char *swallow,
-                       Evas_Object *content)
+elm_layout_box_prepend(Evas_Object *obj,
+                       const char *part,
+                       Evas_Object *child)
 {
    ELM_LAYOUT_CHECK(obj) EINA_FALSE;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE);
+
    Eina_Bool ret = EINA_FALSE;
-   eo_do(obj, elm_obj_container_content_set(swallow, content, &ret));
+   eo_do(obj, elm_obj_layout_box_prepend(part, child, &ret));
    return ret;
 }
 
-EAPI Evas_Object *
-elm_layout_content_get(const Evas_Object *obj,
-                       const char *swallow)
+static void
+_elm_layout_smart_box_prepend(Eo *obj, void *_pd, va_list *list)
 {
-   ELM_LAYOUT_CHECK(obj) NULL;
-   Evas_Object *ret = NULL;
-   eo_do((Eo *) obj, elm_obj_container_content_get(swallow, &ret));
-   return ret;
-}
+   Elm_Layout_Sub_Object_Data *sub_d;
 
-EAPI Evas_Object *
-elm_layout_content_unset(Evas_Object *obj,
-                         const char *swallow)
-{
-   ELM_LAYOUT_CHECK(obj) NULL;
-   Evas_Object *ret = NULL;
-   eo_do(obj, elm_obj_container_content_unset(swallow, &ret));
-   return ret;
-}
+   const char *part = va_arg(*list, const char *);
+   Evas_Object *child = va_arg(*list, Evas_Object *);
+   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+   if (ret) *ret = EINA_FALSE;
 
-EAPI Eina_Bool
-elm_layout_text_set(Evas_Object *obj,
-                    const char *part,
-                    const char *text)
-{
-   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
-   Eina_Bool ret = EINA_FALSE;
-   text = elm_widget_part_text_translate(obj, part, text);
-   eo_do(obj, elm_obj_layout_text_set(part, text, &ret));
-   return ret;
-}
+   Elm_Layout_Smart_Data *sd = _pd;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
 
-EAPI const char *
-elm_layout_text_get(const Evas_Object *obj,
-                    const char *part)
-{
-   ELM_LAYOUT_CHECK(obj) NULL;
+   if (!edje_object_part_box_prepend
+         (wd->resize_obj, part, child))
+     {
+        ERR("child %p could not be prepended to box part '%s'", child, part);
+        return;
+     }
 
-   const char *ret = NULL;
-   eo_do((Eo *) obj, elm_obj_layout_text_get(part, &ret));
-   return ret;
+   if (!elm_widget_sub_object_add(obj, child))
+     {
+        edje_object_part_box_remove
+          (wd->resize_obj, part, child);
+        return;
+     }
+
+   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
+   sub_d->type = BOX_PREPEND;
+   sub_d->part = eina_stringshare_add(part);
+   sub_d->obj = child;
+   sd->subs = eina_list_prepend(sd->subs, sub_d);
+
+   if (wd->frozen) goto end;;
+   eo_do(obj, elm_obj_layout_sizing_eval());
+
+end:
+   if (ret) *ret = EINA_TRUE;
 }
 
 EAPI Eina_Bool
-elm_layout_box_append(Evas_Object *obj,
-                      const char *part,
-                      Evas_Object *child)
+elm_layout_box_insert_before(Evas_Object *obj,
+                             const char *part,
+                             Evas_Object *child,
+                             const Evas_Object *reference)
 {
    ELM_LAYOUT_CHECK(obj) EINA_FALSE;
    EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(reference, EINA_FALSE);
 
    Eina_Bool ret = EINA_FALSE;
-   eo_do(obj, elm_obj_layout_box_append(part, child, &ret));
+   eo_do(obj, elm_obj_layout_box_insert_before(part, child, reference, &ret));
    return ret;
 }
 
-EAPI Eina_Bool
-elm_layout_box_prepend(Evas_Object *obj,
-                       const char *part,
-                       Evas_Object *child)
+static void
+_elm_layout_smart_box_insert_before(Eo *obj, void *_pd, va_list *list)
 {
-   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE);
+   Elm_Layout_Sub_Object_Data *sub_d;
 
-   Eina_Bool ret = EINA_FALSE;
-   eo_do(obj, elm_obj_layout_box_prepend(part, child, &ret));
-   return ret;
-}
+   const char *part = va_arg(*list, const char *);
+   Evas_Object *child = va_arg(*list, Evas_Object *);
+   const Evas_Object *reference = va_arg(*list, const Evas_Object *);
+   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+   if (ret) *ret = EINA_FALSE;
+
+   Elm_Layout_Smart_Data *sd = _pd;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+
+   if (!edje_object_part_box_insert_before
+         (wd->resize_obj, part, child, reference))
+     {
+        ERR("child %p could not be inserted before %p inf box part '%s'",
+            child, reference, part);
+        return;
+     }
+
+   if (!elm_widget_sub_object_add(obj, child))
+     {
+        edje_object_part_box_remove
+          (wd->resize_obj, part, child);
+        return;
+     }
+
+   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
+   sub_d->type = BOX_INSERT_BEFORE;
+   sub_d->part = eina_stringshare_add(part);
+   sub_d->obj = child;
+   sub_d->p.box.reference = reference;
+   sd->subs = eina_list_append(sd->subs, sub_d);
+
+   evas_object_event_callback_add
+     ((Evas_Object *)reference, EVAS_CALLBACK_DEL, _box_reference_del, sub_d);
 
-EAPI Eina_Bool
-elm_layout_box_insert_before(Evas_Object *obj,
-                             const char *part,
-                             Evas_Object *child,
-                             const Evas_Object *reference)
-{
-   ELM_LAYOUT_CHECK(obj) EINA_FALSE;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(reference, EINA_FALSE);
+   if (wd->frozen) goto end;
+   eo_do(obj, elm_obj_layout_sizing_eval());
 
-   Eina_Bool ret = EINA_FALSE;
-   eo_do(obj, elm_obj_layout_box_insert_before(part, child, reference, &ret));
-   return ret;
+end:
+   if (ret) *ret = EINA_TRUE;
 }
 
 EAPI Eina_Bool
@@ -1670,6 +1430,49 @@ elm_layout_box_insert_at(Evas_Object *obj,
    return ret;
 }
 
+static void
+_elm_layout_smart_box_insert_at(Eo *obj, void *_pd, va_list *list)
+{
+   Elm_Layout_Sub_Object_Data *sub_d;
+
+   const char *part = va_arg(*list, const char *);
+   Evas_Object *child = va_arg(*list, Evas_Object *);
+   unsigned int pos = va_arg(*list, unsigned int);
+   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+   if (ret) *ret = EINA_FALSE;
+
+   Elm_Layout_Smart_Data *sd = _pd;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+
+   if (!edje_object_part_box_insert_at
+         (wd->resize_obj, part, child, pos))
+     {
+        ERR("child %p could not be inserted at %u to box part '%s'",
+            child, pos, part);
+        return;
+     }
+
+   if (!elm_widget_sub_object_add(obj, child))
+     {
+        edje_object_part_box_remove
+          (wd->resize_obj, part, child);
+        return;
+     }
+
+   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
+   sub_d->type = BOX_INSERT_AT;
+   sub_d->part = eina_stringshare_add(part);
+   sub_d->obj = child;
+   sub_d->p.box.pos = pos;
+   sd->subs = eina_list_append(sd->subs, sub_d);
+
+   if (wd->frozen) goto end;
+   eo_do(obj, elm_obj_layout_sizing_eval());
+
+end:
+   if (ret) *ret = EINA_TRUE;
+}
+
 EAPI Evas_Object *
 elm_layout_box_remove(Evas_Object *obj,
                       const char *part,
@@ -1682,6 +1485,36 @@ elm_layout_box_remove(Evas_Object *obj,
    return ret;
 }
 
+static void
+_elm_layout_smart_box_remove(Eo *obj, void *_pd, va_list *list)
+{
+
+   const char *part = va_arg(*list, const char *);
+   Evas_Object *child = va_arg(*list, Evas_Object *);
+   Evas_Object **ret = va_arg(*list, Evas_Object **);
+   if (ret) *ret = NULL;
+   Evas_Object *int_ret = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN(part);
+   EINA_SAFETY_ON_NULL_RETURN(child);
+
+   Elm_Layout_Smart_Data *sd = _pd;
+
+   const Eina_List *l;
+   Elm_Layout_Sub_Object_Data *sub_d;
+
+   EINA_LIST_FOREACH(sd->subs, l, sub_d)
+     {
+        if (!_sub_box_is(sub_d)) continue;
+        if ((sub_d->obj == child) && (!strcmp(sub_d->part, part)))
+          {
+             int_ret = _sub_box_remove(obj, sd, sub_d);
+             if (ret) *ret = int_ret;
+             return;
+          }
+     }
+}
+
 EAPI Eina_Bool
 elm_layout_box_remove_all(Evas_Object *obj,
                           const char *part,
@@ -1694,6 +1527,42 @@ elm_layout_box_remove_all(Evas_Object *obj,
    return ret;
 }
 
+static void
+_elm_layout_smart_box_remove_all(Eo *obj, void *_pd, va_list *list)
+{
+   const char *part = va_arg(*list, const char *);
+   Eina_Bool clear = va_arg(*list, int);
+   Eina_Bool *ret= va_arg(*list, Eina_Bool *);
+   if (ret) *ret = EINA_FALSE;
+
+   EINA_SAFETY_ON_NULL_RETURN(part);
+
+   Elm_Layout_Smart_Data *sd = _pd;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+
+   Elm_Layout_Sub_Object_Data *sub_d;
+   Eina_List *lst;
+
+   lst = eina_list_clone(sd->subs);
+   EINA_LIST_FREE(lst, sub_d)
+     {
+        if (!_sub_box_is(sub_d)) continue;
+        if (!strcmp(sub_d->part, part))
+          {
+             /* original item's deletion handled at sub-obj-del */
+             Evas_Object *child = _sub_box_remove(obj, sd, sub_d);
+             if ((clear) && (child)) evas_object_del(child);
+          }
+     }
+
+   /* eventually something may not be added with elm_layout, delete them
+    * as well */
+   edje_object_part_box_remove_all
+     (wd->resize_obj, part, clear);
+
+   if (ret) *ret = EINA_TRUE;
+}
+
 EAPI Eina_Bool
 elm_layout_table_pack(Evas_Object *obj,
                       const char *part,
@@ -1710,6 +1579,57 @@ elm_layout_table_pack(Evas_Object *obj,
    return ret;
 }
 
+static void
+_elm_layout_smart_table_pack(Eo *obj, void *_pd, va_list *list)
+{
+   Elm_Layout_Sub_Object_Data *sub_d;
+
+   const char *part = va_arg(*list, const char *);
+   Evas_Object *child = va_arg(*list, Evas_Object *);
+   unsigned short col = va_arg(*list, unsigned int);
+   unsigned short row = va_arg(*list, unsigned int);
+   unsigned short colspan = va_arg(*list, unsigned int);
+   unsigned short rowspan = va_arg(*list, unsigned int);
+   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+   if (ret) *ret = EINA_FALSE;
+
+   Elm_Layout_Smart_Data *sd = _pd;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+
+   if (!edje_object_part_table_pack
+         (wd->resize_obj, part, child, col,
+         row, colspan, rowspan))
+     {
+        ERR("child %p could not be packed into box part '%s' col=%uh, row=%hu,"
+            " colspan=%hu, rowspan=%hu", child, part, col, row, colspan,
+            rowspan);
+        return;
+     }
+
+   if (!elm_widget_sub_object_add(obj, child))
+     {
+        edje_object_part_table_unpack
+          (wd->resize_obj, part, child);
+        return;
+     }
+
+   sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data);
+   sub_d->type = TABLE_PACK;
+   sub_d->part = eina_stringshare_add(part);
+   sub_d->obj = child;
+   sub_d->p.table.col = col;
+   sub_d->p.table.row = row;
+   sub_d->p.table.colspan = colspan;
+   sub_d->p.table.rowspan = rowspan;
+   sd->subs = eina_list_append(sd->subs, sub_d);
+
+   if (wd->frozen) goto end;
+   eo_do(obj, elm_obj_layout_sizing_eval());
+
+end:
+   if (ret) *ret = EINA_TRUE;
+}
+
 EAPI Evas_Object *
 elm_layout_table_unpack(Evas_Object *obj,
                         const char *part,
@@ -1722,6 +1642,36 @@ elm_layout_table_unpack(Evas_Object *obj,
    return ret;
 }
 
+static void
+_elm_layout_smart_table_unpack(Eo *obj, void *_pd, va_list *list)
+{
+
+   const char *part = va_arg(*list, const char *);
+   Evas_Object *child = va_arg(*list, Evas_Object *);
+   Evas_Object **ret = va_arg(*list, Evas_Object **);
+   if (ret) *ret = NULL;
+   Evas_Object *int_ret = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN(part);
+   EINA_SAFETY_ON_NULL_RETURN(child);
+
+   Elm_Layout_Smart_Data *sd = _pd;
+
+   const Eina_List *l;
+   Elm_Layout_Sub_Object_Data *sub_d;
+
+   EINA_LIST_FOREACH(sd->subs, l, sub_d)
+     {
+        if (sub_d->type != TABLE_PACK) continue;
+        if ((sub_d->obj == child) && (!strcmp(sub_d->part, part)))
+          {
+             int_ret = _sub_table_remove(obj, sd, sub_d);
+             if (ret) *ret = int_ret;
+             return;
+          }
+     }
+}
+
 EAPI Eina_Bool
 elm_layout_table_clear(Evas_Object *obj,
                        const char *part,
@@ -1734,6 +1684,41 @@ elm_layout_table_clear(Evas_Object *obj,
    return ret;
 }
 
+static void
+_elm_layout_smart_table_clear(Eo *obj, void *_pd, va_list *list)
+{
+   const char *part = va_arg(*list, const char *);
+   Eina_Bool clear = va_arg(*list, int);
+   Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+   if (ret) *ret = EINA_FALSE;
+
+   EINA_SAFETY_ON_NULL_RETURN(part);
+
+   Elm_Layout_Smart_Data *sd = _pd;
+   Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS);
+
+   Elm_Layout_Sub_Object_Data *sub_d;
+   Eina_List *lst;
+
+   lst = eina_list_clone(sd->subs);
+   EINA_LIST_FREE(lst, sub_d)
+     {
+        if (sub_d->type != TABLE_PACK) continue;
+        if (!strcmp(sub_d->part, part))
+          {
+             /* original item's deletion handled at sub-obj-del */
+             Evas_Object *child = _sub_table_remove(obj, sd, sub_d);
+             if ((clear) && (child)) evas_object_del(child);
+          }
+     }
+
+   /* eventually something may not be added with elm_layout, delete them
+    * as well */
+   edje_object_part_table_clear(wd->resize_obj, part, clear);
+
+   if (ret) *ret = EINA_TRUE;
+}
+
 EAPI Evas_Object *
 elm_layout_edje_get(const Evas_Object *obj)
 {
@@ -1781,6 +1766,21 @@ elm_layout_sizing_eval(Evas_Object *obj)
    eo_do(obj, elm_obj_layout_sizing_eval());
 }
 
+/* layout's sizing evaluation is deferred. evaluation requests are
+ * queued up and only flag the object as 'changed'. when it comes to
+ * Evas's rendering phase, it will be addressed, finally (see
+ * _elm_layout_smart_calculate()). */
+static void
+_elm_layout_smart_sizing_eval(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
+{
+   Elm_Layout_Smart_Data *sd = _pd;
+
+   if (sd->needs_size_calc) return;
+   sd->needs_size_calc = EINA_TRUE;
+
+   evas_object_smart_changed(obj);
+}
+
 EAPI int
 elm_layout_freeze(Evas_Object *obj)
 {