From: Daniel Juyung Seo Date: Thu, 29 Aug 2013 07:39:20 +0000 (+0900) Subject: elm_layout.c: refactoring. moved code around for better readability like other eo... X-Git-Tag: submit/devel/efl/20131029.104556~248 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b8a4b7cd559e26143e665b44284264379f40738c;p=platform%2Fupstream%2Felementary.git elm_layout.c: refactoring. moved code around for better readability like other eo codes. --- diff --git a/src/lib/elm_layout.c b/src/lib/elm_layout.c index 41d5fbb..597aa15 100644 --- a/src/lib/elm_layout.c +++ b/src/lib/elm_layout.c @@ -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) {