From 443f8aafaa2294a048db8e1755d2ae377dc610a8 Mon Sep 17 00:00:00 2001 From: Sohyun Kim Date: Tue, 8 Jun 2010 19:28:35 +0900 Subject: [PATCH] [Navigationbar][pager]merge --- src/lib/Elementary.h.in | 5 + src/lib/elm_navigationbar.c | 598 +++++++++++++++++++++++++++++++++++--------- src/lib/elm_pager.c | 60 ++++- 3 files changed, 544 insertions(+), 119 deletions(-) diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index 79a5404..ceb64f9 100755 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -1244,6 +1244,7 @@ extern "C" { EAPI Evas_Object *elm_pager_add(Evas_Object *parent); EAPI void elm_pager_content_push(Evas_Object *obj, Evas_Object *content); EAPI void elm_pager_content_pop(Evas_Object *obj); + EAPI void elm_pager_to_content_pop(Evas_Object *obj, Evas_Object *content); EAPI void elm_pager_content_promote(Evas_Object *obj, Evas_Object *content); EAPI Evas_Object *elm_pager_content_bottom_get(const Evas_Object *obj); EAPI Evas_Object *elm_pager_content_top_get(const Evas_Object *obj); @@ -1926,8 +1927,11 @@ extern "C" { EAPI Evas_Object *elm_navigationbar_add(Evas_Object *parent); EAPI void elm_navigationbar_push(Evas_Object *obj, const char *title, Evas_Object *left_btn, Evas_Object *right_btn, Evas_Object *content, Eina_Bool animation); EAPI void elm_navigationbar_pop(Evas_Object *obj, Eina_Bool animation); + EAPI void elm_navigationbar_to_content_pop(Evas_Object *obj, Evas_Object *content, Eina_Bool animation); EAPI void elm_navigationbar_title_set(Evas_Object *obj, Evas_Object *content, const char *title); EAPI const char *elm_navigationbar_title_get(Evas_Object *obj, Evas_Object *content); + EAPI void elm_navigationbar_title_object_add(Evas_Object *obj, Evas_Object *content, Evas_Object *title_obj); + EAPI Eina_List *elm_navigationbar_title_object_list_get(Evas_Object *obj, Evas_Object *content); EAPI void elm_navigationbar_back_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Eina_Bool animation); EAPI Evas_Object *elm_navigationbar_back_button_get(Evas_Object *obj, Evas_Object *content); EAPI void elm_navigationbar_left_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Eina_Bool animation); @@ -1935,6 +1939,7 @@ extern "C" { EAPI void elm_navigationbar_right_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Eina_Bool animation); EAPI Evas_Object *elm_navigationbar_right_button_get(Evas_Object *obj, Evas_Object *content); EAPI Evas_Object *elm_navigationbar_content_top_get(Evas_Object *obj); + EAPI Evas_Object *elm_navigationbar_content_root_get(Evas_Object *obj); EAPI void elm_navigationbar_hidden_set(Evas_Object *obj, Eina_Bool hidden, Eina_Bool animation); diff --git a/src/lib/elm_navigationbar.c b/src/lib/elm_navigationbar.c index d76ae63..7e75808 100755 --- a/src/lib/elm_navigationbar.c +++ b/src/lib/elm_navigationbar.c @@ -35,6 +35,8 @@ struct _Item { Evas_Object *obj; Evas_Object *title; + Evas_Object *title_obj; + Eina_List *title_list; Evas_Object *left_btn; Evas_Object *right_btn; Evas_Object *back_btn; @@ -67,12 +69,15 @@ static void _sizing_eval(Evas_Object *obj); static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _item_sizing_eval(Item *it); +static void _delete_item(Item *it); static void _back_button_clicked(void *data, Evas_Object *obj, void *event_info); static int _get_button_width(Evas_Object *obj, Eina_Bool back_btn); static Eina_Bool _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_Bool back_btn); static const char *_title_string_get(Evas_Object *title); static void _label_set(Evas_Object* label, const char* title); +static Evas_Object *_multiple_object_set(Evas_Object *obj, Evas_Object *sub_obj, Eina_List *list, int width); +static Item *_check_item_is_added(Evas_Object *obj, Evas_Object *content); static void _transition_complete_cb(void *data); static Elm_Transit *_transition_set(Item* prev_it, Item *it, Evas_Coord y, Eina_Bool pop); @@ -81,8 +86,15 @@ static void _del_hook(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *ll; + Item *it; + + EINA_LIST_FOREACH(wd->stack, ll, it) + _delete_item(it); - elm_widget_sub_object_del(obj, wd->pager); + eina_list_free(wd->stack); + evas_object_del(wd->pager); + evas_object_del(wd->base); free(wd); } @@ -109,19 +121,44 @@ _theme_hook(Evas_Object *obj) } static void +_delete_item(Item *it) +{ + Eina_List *ll; + Evas_Object *list_obj; + + evas_object_del(it->left_btn); + evas_object_del(it->back_btn); + evas_object_del(it->right_btn); + evas_object_del(it->title_obj); + evas_object_del(it->title); + + EINA_LIST_FOREACH(it->title_list, ll, list_obj) + evas_object_del(list_obj); + eina_list_free(it->title_list); + + free(it); +} + +static void _sizing_eval(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; + Evas_Coord w = -1, h = -1; Eina_List *ll; - Item *it; edje_object_size_min_calc(wd->base, &minw, &minh); + evas_object_size_hint_min_get(obj, &w, &h); + if (w > minw) minw = w; + if (h > minw) minh = h; + evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, -1, -1); - EINA_LIST_FOREACH(wd->stack, ll, it) + ll = eina_list_last(wd->stack); + if (ll) { + Item *it = ll->data; _item_sizing_eval(it); } } @@ -130,22 +167,31 @@ static void _item_sizing_eval(Item *it) { Widget_Data *wd = elm_widget_data_get(it->obj); - Evas_Coord pad, height, minw; + Evas_Coord pad, height, minw, w; + int pad_count = 2; + + if (!it) return; edje_object_size_min_calc(wd->base, &minw, NULL); - edje_object_part_geometry_get(wd->base, "elm.rect.pad2", NULL, NULL, &pad, &height); + evas_object_geometry_get(wd->base, NULL, NULL, &w, NULL); + if (w < minw) w = minw; + + edje_object_part_geometry_get(wd->base, "elm.rect.pad1", NULL, NULL, &pad, NULL); + edje_object_part_geometry_get(wd->base, "elm.swallow.title", NULL, NULL, NULL, &height); if (it->left_btn) { it->left_btn_w = _get_button_width(it->left_btn, FALSE); evas_object_resize(it->left_btn, it->left_btn_w , height); evas_object_size_hint_min_set(it->left_btn, it->left_btn_w , height); + pad_count++; } else if (it->back_btn) { it->left_btn_w = _get_button_width(it->back_btn, TRUE); evas_object_resize(it->back_btn, it->left_btn_w, height); evas_object_size_hint_min_set(it->back_btn, it->left_btn_w, height); + pad_count++; } if (it->right_btn) @@ -153,13 +199,21 @@ _item_sizing_eval(Item *it) it->right_btn_w = _get_button_width(it->right_btn, FALSE); evas_object_resize(it->right_btn, it->right_btn_w, height); evas_object_size_hint_min_set(it->right_btn, it->right_btn_w, height); + pad_count++; } - if (it->title) + if (it->title_list) + { + it->title_w = w - it->left_btn_w - it->right_btn_w - pad_count * pad; + it->title_obj = _multiple_object_set(it->obj, it->title_obj, it->title_list, it->title_w); + evas_object_resize(it->title_obj, it->title_w, height); + evas_object_size_hint_min_set(it->title_obj, it->title_w, height); + } + else if (it->title) { const char *str = NULL; - it->title_w = minw - it->left_btn_w - it->right_btn_w - 4*pad; + it->title_w = w - it->left_btn_w - it->right_btn_w - pad_count * pad; evas_object_resize(it->title, it->title_w, height); evas_object_size_hint_min_set(it->title, it->title_w, height); @@ -168,8 +222,13 @@ _item_sizing_eval(Item *it) { double align; const char align_str[7] = {0,}; + int diff = 0; - align = 0.5 - ((it->left_btn_w-it->right_btn_w)/(double)it->title_w); + diff = it->left_btn_w - it->right_btn_w; + if (it->left_btn_w) diff += pad; + if (it->right_btn_w) diff -= pad; + + align = 0.5 - diff / (double)w; if (align < 0.0) align = 0.0; sprintf(align_str, "%lf", align); elm_label_text_align_set(it->title, align_str); @@ -178,23 +237,9 @@ _item_sizing_eval(Item *it) } static void -_move(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - Evas_Coord x, y; - - evas_object_geometry_get(obj, &x, &y, NULL, NULL); - - /* add sub object moving!!!! */ -} - -static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info) { - Evas_Coord w, h; - - evas_object_geometry_get(obj, NULL, NULL, &w, &h); - - /* add sub object resizing!!!! */ + _sizing_eval(obj); } static void @@ -213,78 +258,98 @@ _transition_complete_cb(void *data) if (cb->pop && prev_it) { Eina_List *ll; - - if (prev_it->left_btn) elm_widget_sub_object_del(prev_it->obj, prev_it->left_btn); - else if (prev_it->back_btn) elm_widget_sub_object_del(prev_it->obj, prev_it->back_btn); - if (prev_it->right_btn) elm_widget_sub_object_del(prev_it->obj, prev_it->right_btn); - if (prev_it->title) elm_widget_sub_object_del(prev_it->obj, prev_it->title); - - evas_object_del(prev_it->left_btn); - evas_object_del(prev_it->back_btn); - evas_object_del(prev_it->right_btn); - evas_object_del(prev_it->title); - ll = eina_list_last(wd->stack); if (ll->data == prev_it) { + _delete_item(prev_it); wd->stack = eina_list_remove_list(wd->stack, ll); - free(prev_it); } } else if (prev_it) { evas_object_hide(prev_it->left_btn); evas_object_hide(prev_it->back_btn); + evas_object_hide(prev_it->title_obj); evas_object_hide(prev_it->title); evas_object_hide(prev_it->right_btn); } if (it) { - if (it->left_btn) edje_object_part_swallow(wd->base, "elm.swallow.btn1", it->left_btn); - else if (it->back_btn) edje_object_part_swallow(wd->base, "elm.swallow.btn1", it->back_btn); - if (it->right_btn) edje_object_part_swallow(wd->base, "elm.swallow.btn2", it->right_btn); - if (it->title) edje_object_part_swallow(wd->base, "elm.swallow.title", it->title); + if (it->left_btn) + { + edje_object_signal_emit(wd->base, "elm,state,item,add,leftpad", "elm"); + edje_object_part_swallow(wd->base, "elm.swallow.btn1", it->left_btn); + } + else if (it->back_btn) + { + edje_object_signal_emit(wd->base, "elm,state,item,add,leftpad", "elm"); + edje_object_part_swallow(wd->base, "elm.swallow.btn1", it->back_btn); + } + else + edje_object_signal_emit(wd->base, "elm,state,item,reset,leftpad", "elm"); + + if (it->right_btn) + { + edje_object_signal_emit(wd->base, "elm,state,item,add,rightpad", "elm"); + edje_object_part_swallow(wd->base, "elm.swallow.btn2", it->right_btn); + } + else + edje_object_signal_emit(wd->base, "elm,state,item,reset,rightpad", "elm"); + + if (it->title_obj) edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj); + else if (it->title) edje_object_part_swallow(wd->base, "elm.swallow.title", it->title); } free(cb); + + evas_object_smart_callback_call(it->obj, "updated", it->content); } static Elm_Transit * _transition_set(Item* prev_it, Item *it, Evas_Coord y, Eina_Bool pop) { Widget_Data *wd = elm_widget_data_get(it->obj); - Evas_Coord pad, minw; + Evas_Coord pad, w; Elm_Transit *transit; int num = 1; + int pad_count; transit = elm_transit_add(it->obj); edje_object_part_geometry_get(wd->base, "elm.rect.pad1", NULL, NULL, &pad, NULL); - edje_object_size_min_calc(wd->base, &minw, NULL); + evas_object_geometry_get(wd->base, NULL, NULL, &w, NULL); if (pop) num = -1; // hide prev item if (prev_it) { + pad_count = 1; if (prev_it->left_btn) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(prev_it->left_btn, pad, y, pad-num*EFFECT_WIDTH/4, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(prev_it->left_btn, pad, y, pad-num*EFFECT_WIDTH/4, y)); elm_transit_fx_insert(transit, elm_fx_color_add(prev_it->left_btn, 255, 255, 255, 255, 0, 0, 0, 0)); + pad_count++; } else if (prev_it->back_btn) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(prev_it->back_btn, pad, y, pad-num*EFFECT_WIDTH/4, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(prev_it->back_btn, pad, y, pad-num*EFFECT_WIDTH/4, y)); elm_transit_fx_insert(transit, elm_fx_color_add(prev_it->back_btn, 255, 255, 255, 255, 0, 0, 0, 0)); + pad_count++; + } + if (prev_it->title_obj) + { + elm_transit_fx_insert(transit, elm_fx_translation_add(prev_it->title_obj, prev_it->left_btn_w+pad_count*pad, y, prev_it->left_btn_w+pad_count*pad-num*EFFECT_WIDTH, y)); + elm_transit_fx_insert(transit, elm_fx_color_add(prev_it->title_obj, 255, 255, 255, 255, 0, 0, 0, 0)); } - if (prev_it->title) + else if (prev_it->title) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(prev_it->title, prev_it->left_btn_w+2*pad, y, prev_it->left_btn_w+2*pad-num*EFFECT_WIDTH, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(prev_it->title, prev_it->left_btn_w+pad_count*pad, y, prev_it->left_btn_w+pad_count*pad-num*EFFECT_WIDTH, y)); elm_transit_fx_insert(transit, elm_fx_color_add(prev_it->title, 255, 255, 255, 255, 0, 0, 0, 0)); } if (prev_it->right_btn) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(prev_it->right_btn, minw-pad-prev_it->right_btn_w, y, minw-pad-prev_it->right_btn_w-num*EFFECT_WIDTH/4, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(prev_it->right_btn, w-pad-prev_it->right_btn_w, y, w-pad-prev_it->right_btn_w-num*EFFECT_WIDTH/4, y)); elm_transit_fx_insert(transit, elm_fx_color_add(prev_it->right_btn, 255, 255, 255, 255, 0, 0, 0, 0)); } } @@ -292,24 +357,32 @@ _transition_set(Item* prev_it, Item *it, Evas_Coord y, Eina_Bool pop) // show new item if (it) { + pad_count = 1; if (it->left_btn) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(it->left_btn, pad+num*EFFECT_WIDTH/4, y, pad, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(it->left_btn, pad+num*EFFECT_WIDTH/4, y, pad, y)); elm_transit_fx_insert(transit, elm_fx_color_add(it->left_btn, 0, 0, 0, 0, 255, 255, 255, 255)); + pad_count++; } else if (it->back_btn) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(it->back_btn, pad+num*EFFECT_WIDTH/4, y, pad, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(it->back_btn, pad+num*EFFECT_WIDTH/4, y, pad, y)); elm_transit_fx_insert(transit, elm_fx_color_add(it->back_btn, 0, 0, 0, 0, 255, 255, 255, 255)); + pad_count++; + } + if (it->title_obj) + { + elm_transit_fx_insert(transit, elm_fx_translation_add(it->title_obj, it->left_btn_w+pad_count*pad+num*EFFECT_WIDTH, y, it->left_btn_w+pad_count*pad, y)); + elm_transit_fx_insert(transit, elm_fx_color_add(it->title_obj, 0, 0, 0, 0, 255, 255, 255, 255)); } - if (it->title) + else if (it->title) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(it->title, it->left_btn_w+2*pad+num*EFFECT_WIDTH, y, it->left_btn_w+2*pad, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(it->title, it->left_btn_w+pad_count*pad+num*EFFECT_WIDTH, y, it->left_btn_w+pad_count*pad, y)); elm_transit_fx_insert(transit, elm_fx_color_add(it->title, 0, 0, 0, 0, 255, 255, 255, 255)); } if (it->right_btn) { - elm_transit_fx_insert(transit, elm_fx_transfer_add(it->right_btn, minw-pad-it->right_btn_w+num*EFFECT_WIDTH/4, y, minw-pad-it->right_btn_w, y)); + elm_transit_fx_insert(transit, elm_fx_translation_add(it->right_btn, w-pad-it->right_btn_w+num*EFFECT_WIDTH/4, y, w-pad-it->right_btn_w, y)); elm_transit_fx_insert(transit, elm_fx_color_add(it->right_btn, 0, 0, 0, 0, 255, 255, 255, 255)); } } @@ -333,7 +406,7 @@ _get_button_width(Evas_Object *obj, Eina_Bool back_btn) char *label; int btn_len = 0; - if (back_btn) btn_len = BACK_BTN_PADDING; + //if (back_btn) btn_len = BACK_BTN_PADDING; evas_object_geometry_get(elm_button_icon_get(obj), NULL, NULL, &len, NULL); if (len > 0) @@ -366,8 +439,8 @@ _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_ if ((new_btn) && (prev_btn != new_btn)) { - if (back_btn) elm_object_style_set( new_btn, "backkey" ); - else elm_object_style_set(new_btn, "custom/darkblue"); + if (back_btn) elm_object_style_set( new_btn, "navigationbar/back" ); + else elm_object_style_set(new_btn, "navigationbar/normal"); elm_widget_sub_object_add(obj, new_btn); changed = TRUE; } @@ -378,7 +451,7 @@ _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_ static const char * _title_string_get(Evas_Object *title) { - if (!title) return; + if (!title) return NULL; const char *str = NULL; @@ -401,6 +474,64 @@ _label_set(Evas_Object* label, const char* title) elm_label_text_color_set(label, 255, 255, 255, 255); } +static Item * +_check_item_is_added(Evas_Object *obj, Evas_Object *content) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *ll; + Item *it; + + EINA_LIST_FOREACH(wd->stack, ll, it) + { + if (it->content == content) + { + return it; + } + } + return NULL; +} + +static Evas_Object * +_multiple_object_set(Evas_Object *obj, Evas_Object *sub_obj, Eina_List *list, int width) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *ll; + Evas_Object *new_obj, *list_obj; + Evas_Coord pad, height; + char buf[32]; + int num = 1; + int count; + + edje_object_part_geometry_get(wd->base, "elm.rect.pad1", NULL, NULL, &pad, NULL); + edje_object_part_geometry_get(wd->base, "elm.swallow.title", NULL, NULL, NULL, &height); + + if (!sub_obj) + { + new_obj = elm_layout_add(obj); + elm_widget_sub_object_add(obj, new_obj); + elm_layout_theme_set(new_obj, "navigationbar", "title", "default"); + } + else + new_obj = sub_obj; + + count = eina_list_count(list); + EINA_LIST_FOREACH(list, ll, list_obj) + { + evas_object_resize(list_obj, (width-(count-1)*pad)/count, height); + evas_object_size_hint_min_set(list_obj, (width-(count-1)*pad)/count, height); + + memset(buf, 0, sizeof(buf)); + sprintf(buf, "elm,state,item,add,%d", num); + edje_object_signal_emit(elm_layout_edje_get(new_obj), buf, "elm"); + + memset(buf, 0, sizeof(buf)); + sprintf(buf, "elm.swallow.title%d", num++); + elm_layout_content_set(new_obj, buf, list_obj); + } + + return new_obj; +} + /** * Add a new navigatgationbar to the parent * @@ -433,6 +564,8 @@ elm_navigationbar_add(Evas_Object *parent) elm_widget_sub_object_add(obj, wd->pager); edje_object_part_swallow(wd->base, "elm.swallow.content", wd->pager); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, NULL); + _sizing_eval(obj); return obj; } @@ -461,28 +594,50 @@ elm_navigationbar_push(Evas_Object *obj, { Widget_Data *wd = elm_widget_data_get(obj); Eina_List *ll; - Item *it = ELM_NEW(Item); + Item *it; Item *prev_it = NULL; + if (!wd) return; + + it = _check_item_is_added(obj, content); + if (!it) it = ELM_NEW(Item); if (!it) return; - // add new items + // add and set new items + _button_set(obj, NULL, left_btn, EINA_FALSE); + _button_set(obj, NULL, right_btn, EINA_FALSE); + + ll = eina_list_last(wd->stack); + while (ll) + { + prev_it = ll->data; + if (prev_it->obj) break; //find last pushed item + ll = ll->prev; + prev_it = NULL; + } + it->obj = obj; it->left_btn = left_btn; it->right_btn = right_btn; it->content = content; it->ani = animation; - _button_set(obj, NULL, it->left_btn, EINA_FALSE); - _button_set(obj, NULL, it->right_btn, EINA_FALSE); - - ll = eina_list_last(wd->stack); - if (ll) prev_it = ll->data; - - if (!it->left_btn && prev_it) + if (!left_btn && prev_it) { + char *prev_title; + char *buf = NULL; + int len = 0; + it->back_btn = elm_button_add(obj); - elm_button_label_set(it->back_btn, _title_string_get(prev_it->title)); + prev_title = _title_string_get(prev_it->title); + if (prev_title) len = strlen(prev_title); + if (len > 0) buf = calloc(len+3, sizeof(char)); + if (buf) + { + sprintf(buf, "< %s", prev_title); + elm_button_label_set(it->back_btn, buf); + free(buf); + } evas_object_smart_callback_add(it->back_btn, "clicked", _back_button_clicked, it); _button_set(obj, NULL, it->back_btn, EINA_TRUE); } @@ -502,22 +657,24 @@ elm_navigationbar_push(Evas_Object *obj, cb->prev_it = prev_it; cb->it = it; cb->pop = EINA_FALSE; - evas_object_geometry_get(prev_it->title, NULL, &y, NULL, NULL); + if (prev_it->title_obj) evas_object_geometry_get(prev_it->title_obj, NULL, &y, NULL, NULL); + else evas_object_geometry_get(prev_it->title, NULL, &y, NULL, NULL); + if (prev_it->title_obj) edje_object_part_unswallow(wd->base, prev_it->title_obj); + else if (prev_it->title) edje_object_part_unswallow(wd->base, prev_it->title); if (prev_it->left_btn) edje_object_part_unswallow(wd->base, prev_it->left_btn); else if (prev_it->back_btn) edje_object_part_unswallow(wd->base, prev_it->back_btn); if (prev_it->right_btn) edje_object_part_unswallow(wd->base, prev_it->right_btn); - if (prev_it->title) edje_object_part_unswallow(wd->base, prev_it->title); - if (it->ani) + /*if (it->ani) { Elm_Transit* transit; transit = _transition_set(prev_it, it, y, EINA_FALSE); - elm_transit_completion_set(transit, _transition_complete_cb, cb); + elm_transit_completion_callback_set(transit, _transition_complete_cb, cb); elm_transit_run(transit, 0.3); elm_transit_del(transit); } - else + else*/ { _transition_complete_cb(cb); } @@ -536,8 +693,20 @@ elm_navigationbar_push(Evas_Object *obj, elm_pager_animation_set(wd->pager, it->ani); elm_pager_content_push(wd->pager, it->content); + //push item into the stack. it should be always the tail + if (!_check_item_is_added(obj, content)) wd->stack = eina_list_append(wd->stack, it); - _sizing_eval(obj); + else + { + EINA_LIST_FOREACH(wd->stack, ll, it) + { + if (it->content == content) + { + wd->stack = eina_list_demote_list(wd->stack, ll); + break; + } + } + } } /** @@ -561,51 +730,57 @@ elm_navigationbar_pop(Evas_Object *obj, if (!wd->stack) return; + //find item to be popped and to be shown ll = eina_list_last(wd->stack); if (ll) { prev_it = ll->data; - ll = ll->prev; + while (ll = ll->prev) + { + it = ll->data; + if (it->obj) break; + it = NULL; + } } - if (ll) + if (prev_it && it) { - it = ll->data; - // unswallow items and start trasition - if (prev_it) - { - Evas_Coord y; - Transit_Cb_Data *cb = ELM_NEW(Transit_Cb_Data); - - cb->prev_it = prev_it; - cb->it = it; - cb->pop = EINA_TRUE; - evas_object_geometry_get(prev_it->title, NULL, &y, NULL, NULL); + //unswallow items and start trasition + Evas_Coord y; + Transit_Cb_Data *cb = ELM_NEW(Transit_Cb_Data); + + cb->prev_it = prev_it; + cb->it = it; + cb->pop = EINA_TRUE; + if (prev_it->title_obj) evas_object_geometry_get(prev_it->title_obj, NULL, &y, NULL, NULL); + else evas_object_geometry_get(prev_it->title, NULL, &y, NULL, NULL); - if (prev_it->left_btn) edje_object_part_unswallow(wd->base, prev_it->left_btn); - else if (prev_it->back_btn) edje_object_part_unswallow(wd->base, prev_it->back_btn); - if (prev_it->right_btn) edje_object_part_unswallow(wd->base, prev_it->right_btn); - if (prev_it->title) edje_object_part_unswallow(wd->base, prev_it->title); + if (prev_it->title_obj) edje_object_part_unswallow(wd->base, prev_it->title_obj); + else if (prev_it->title) edje_object_part_unswallow(wd->base, prev_it->title); + if (prev_it->left_btn) edje_object_part_unswallow(wd->base, prev_it->left_btn); + else if (prev_it->back_btn) edje_object_part_unswallow(wd->base, prev_it->back_btn); + if (prev_it->right_btn) edje_object_part_unswallow(wd->base, prev_it->right_btn); - if (animation) - { - Elm_Transit* transit; - transit = _transition_set(prev_it, it, y, EINA_TRUE); - elm_transit_completion_set(transit, _transition_complete_cb, cb); - elm_transit_run(transit, 0.3); - elm_transit_del(transit); - } - else - { - _transition_complete_cb(cb); - } + _item_sizing_eval(it); + + /*if (animation) + { + Elm_Transit* transit; + transit = _transition_set(prev_it, it, y, EINA_TRUE); + elm_transit_completion_callback_set(transit, _transition_complete_cb, cb); + elm_transit_run(transit, 0.3); + elm_transit_del(transit); + } + else*/ + { + _transition_complete_cb(cb); } //pop content from pager elm_pager_animation_set(wd->pager, animation); elm_pager_content_pop(wd->pager); } - else + else if (prev_it) { Transit_Cb_Data *cb = ELM_NEW(Transit_Cb_Data); @@ -618,12 +793,99 @@ elm_navigationbar_pop(Evas_Object *obj, elm_pager_animation_set(wd->pager, EINA_FALSE); elm_pager_content_pop(wd->pager); } +} - _sizing_eval(obj); +/** + * Pop to the inputted content object (and update it) + * This pops the objects that is under the inputed content on the navigationbar stack, makes them disappear, then deletes the objects. + * The content will become visible. + * + * @param[in] obj The NavigationBar object + * @param[in] content the object to show + * @param[in] animation transition when this content is popped + * + * @ingroup NavigationBar + */ +EAPI void +elm_navigationbar_to_content_pop(Evas_Object *obj, + Evas_Object *content, + Eina_Bool animation) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *ll; + Item *it = NULL; + Item *prev_it = NULL; + + if (!wd->stack) return; + + //find item to be popped and to be shown + ll = eina_list_last(wd->stack); + if (ll) + { + prev_it = ll->data; + while (ll = ll->prev) + { + it = ll->data; + if (it->obj && (it->content == content)) + { + //delete contents between the top and the inputted content + ll = eina_list_last(wd->stack); + while (ll = ll->prev) + { + if (ll->data == it) break; + else + { + _delete_item(ll->data); + wd->stack = eina_list_remove_list(wd->stack, ll); + } + } + break; + } + it = NULL; + } + } + + if (prev_it && it) + { + //unswallow items and start trasition + Evas_Coord y; + Transit_Cb_Data *cb = ELM_NEW(Transit_Cb_Data); + + cb->prev_it = prev_it; + cb->it = it; + cb->pop = EINA_TRUE; + if (prev_it->title_obj) evas_object_geometry_get(prev_it->title_obj, NULL, &y, NULL, NULL); + else evas_object_geometry_get(prev_it->title, NULL, &y, NULL, NULL); + + if (prev_it->title_obj) edje_object_part_unswallow(wd->base, prev_it->title_obj); + else if (prev_it->title) edje_object_part_unswallow(wd->base, prev_it->title); + if (prev_it->left_btn) edje_object_part_unswallow(wd->base, prev_it->left_btn); + else if (prev_it->back_btn) edje_object_part_unswallow(wd->base, prev_it->back_btn); + if (prev_it->right_btn) edje_object_part_unswallow(wd->base, prev_it->right_btn); + + _item_sizing_eval(it); + + /*if (animation) + { + Elm_Transit* transit; + transit = _transition_set(prev_it, it, y, EINA_TRUE); + elm_transit_completion_callback_set(transit, _transition_complete_cb, cb); + elm_transit_run(transit, 0.3); + elm_transit_del(transit); + } + else*/ + { + _transition_complete_cb(cb); + } + + //pop content from pager + elm_pager_animation_set(wd->pager, animation); + elm_pager_to_content_pop(wd->pager, content); + } } /** - * Set the title string for the content + * Set the title string for the pushed content * If the content is at the top of the navigation stack, update the title string * * @param[in] obj The NavigationBar object @@ -641,6 +903,8 @@ elm_navigationbar_title_set(Evas_Object *obj, Eina_List *ll; Item *it; + if (!wd) return; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) @@ -653,7 +917,7 @@ elm_navigationbar_title_set(Evas_Object *obj, } /** - * Return the title string of the content + * Return the title string of the pushed content * * @param[in] obj The NavigationBar object * @param[in] content The object to push or pushed @@ -669,17 +933,98 @@ elm_navigationbar_title_get(Evas_Object *obj, Eina_List *ll; Item *it; + if (!wd) return NULL; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) return _title_string_get(it->title); } + return NULL; +} +/** + * Add a title object for the content + * If it is added before pushing the content, it will be shown when content is being pushed. + * If the content is at the top of the navigation stack, update the title or title object. + * + * @param[in] obj The NavigationBar object + * @param[in] content The object to push or pushed + * @param[in] title_obj a title object (normally button or segment_control) + * + * @ingroup NavigationBar + */ +EAPI void +elm_navigationbar_title_object_add(Evas_Object *obj, + Evas_Object *content, + Evas_Object *title_obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *ll; + Item *it; + Item *last_it; + + if (!title_obj) return; + if (!wd) return; + + it = _check_item_is_added(obj, content); + if (!it) it = ELM_NEW(Item); + if (!it) return; + + it->content = content; + it->title_list = eina_list_append(it->title_list, title_obj); + if (it->obj) _item_sizing_eval(it); + + if (!_check_item_is_added(obj, content)) + wd->stack = eina_list_append(wd->stack, it); + + //update if the content is the top item + ll = eina_list_last(wd->stack); + if (ll) + { + last_it = ll->data; + if (last_it->content == content) + { + Evas_Object *swallow; + swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.title"); + if (swallow) { + edje_object_part_unswallow(wd->base, swallow); + evas_object_hide(swallow); + } + edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj); + } + } +} + +/** + * Return the title string of the pushed content + * + * @param[in] obj The NavigationBar object + * @param[in] content The object to push or pushed + * @return The list of title objects + * + * @ingroup NavigationBar + */ +EAPI Eina_List * +elm_navigationbar_title_object_list_get(Evas_Object *obj, + Evas_Object *content) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *ll; + Item *it; + + if (!wd) return NULL; + + EINA_LIST_FOREACH(wd->stack, ll, it) + { + if (it->content == content) + return it->title_list; + } return NULL; } /** - * Set the back button object for the content + * Set the back button object for the pushed content * If the content is at the top of the navigation stack, update the back button * If the left button is already set, back button is not created * @@ -701,6 +1046,8 @@ elm_navigationbar_back_button_set(Evas_Object *obj, Item *it; Eina_Bool changed; + if (!wd) return; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) @@ -726,7 +1073,7 @@ elm_navigationbar_back_button_set(Evas_Object *obj, } /** - * Return the back button object of the content + * Return the back button object of the pushed content * * @param[in] obj The NavigationBar object * @param[in] content The object to push or pushed @@ -742,17 +1089,18 @@ elm_navigationbar_back_button_get(Evas_Object *obj, Eina_List *ll; Item *it; + if (!wd) return NULL; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) return it->back_btn; } - return NULL; } /** - * Set the left button object for the content + * Set the left button object for the pushed content * If the content is at the top of the navigation stack, update the left button * * @param[in] obj The NavigationBar object @@ -773,6 +1121,8 @@ elm_navigationbar_left_button_set(Evas_Object *obj, Item *it; Eina_Bool changed; + if (!wd) return; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) @@ -802,7 +1152,7 @@ elm_navigationbar_left_button_set(Evas_Object *obj, } /** - * Return the left button object of the content + * Return the left button object of the pushed content * * @param[in] obj The NavigationBar object * @param[in] content The object to push or pushed @@ -818,17 +1168,18 @@ elm_navigationbar_left_button_get(Evas_Object *obj, Eina_List *ll; Item *it; + if (!wd) return NULL; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) return it->left_btn; } - return NULL; } /** - * set the right button object for the content + * set the right button object for the pushed content * * @param[in] obj The NavigationBar object * @param[in] content The object to push or pushed @@ -848,6 +1199,8 @@ elm_navigationbar_right_button_set(Evas_Object *obj, Item *it; Eina_Bool changed; + if (!wd) return; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) @@ -870,7 +1223,7 @@ elm_navigationbar_right_button_set(Evas_Object *obj, } /** - * Return the right button of the content + * Return the right button of the pushed content * * @param[in] obj The NavigationBar object * @param[in] content The object to push or pushed @@ -886,6 +1239,8 @@ elm_navigationbar_right_button_get(Evas_Object *obj, Eina_List *ll; Item *it; + if (!wd) return NULL; + EINA_LIST_FOREACH(wd->stack, ll, it) { if (it->content == content) @@ -906,11 +1261,29 @@ EAPI Evas_Object * elm_navigationbar_content_top_get(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; return elm_pager_content_top_get(wd->pager); } /** + * Return the content object at the top of the pager stack + * + * @param[in] obj The NavigationBar object + * @return The root content object or NULL if none + * + * @ingroup NavigationBar + */ +EAPI Evas_Object * +elm_navigationbar_content_root_get(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + + return elm_pager_content_bottom_get(wd->pager); +} + +/** * set navigationbar hidden state and update * * @param[in] obj The NavigationBar object @@ -925,6 +1298,7 @@ elm_navigationbar_hidden_set(Evas_Object *obj, Eina_Bool animation) { Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (hidden) edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm"); else edje_object_signal_emit(wd->base, "elm,state,item,movedown", "elm"); diff --git a/src/lib/elm_pager.c b/src/lib/elm_pager.c index bbdc981..d36b8fc 100755 --- a/src/lib/elm_pager.c +++ b/src/lib/elm_pager.c @@ -139,9 +139,9 @@ _eval_top(Evas_Object *obj) if (wd->top->popme) pop = EINA_TRUE; if (ani) { - if (pop) elm_transit_fx_insert( transit, elm_fx_transfer_add(o , 0, y, w, y)); - else elm_transit_fx_insert( transit, elm_fx_transfer_add(o , 0, y, -w, y)); - elm_transit_completion_set( transit, _complete_cb, it); + if (pop) elm_transit_fx_insert( transit, elm_fx_translation_add(o , 0, y, w, y)); + else elm_transit_fx_insert( transit, elm_fx_translation_add(o , 0, y, -w, y)); + elm_transit_completion_callback_set( transit, _complete_cb, it); } else { @@ -162,8 +162,8 @@ _eval_top(Evas_Object *obj) //add show/hide transition direction & animation on/off. 10.04.14 sohyun if (ani && o) { - if (pop) elm_transit_fx_insert( transit, elm_fx_transfer_add(prev_o, -w, y, 0, y)); - else elm_transit_fx_insert( transit, elm_fx_transfer_add(prev_o, w, y, 0, y)); + if (pop) elm_transit_fx_insert( transit, elm_fx_translation_add(prev_o, -w, y, 0, y)); + else elm_transit_fx_insert( transit, elm_fx_translation_add(prev_o, w, y, 0, y)); elm_transit_run( transit, 0.3 ); } elm_transit_del( transit ); @@ -365,8 +365,8 @@ elm_pager_content_pop(Evas_Object *obj) transit = elm_transit_add(obj); evas_object_geometry_get(obj, NULL, &y, &w, NULL); - elm_transit_fx_insert(transit, elm_fx_transfer_add(o , 0, y, w, y)); - elm_transit_completion_set(transit, _complete_cb, it); + elm_transit_fx_insert(transit, elm_fx_translation_add(o , 0, y, w, y)); + elm_transit_completion_callback_set(transit, _complete_cb, it); elm_transit_run(transit, 0.3 ); elm_transit_del(transit); } @@ -389,6 +389,52 @@ elm_pager_content_pop(Evas_Object *obj) } /** + * Pop to the object that is on the stack + * + * This pops the objects that are on the stack, makes them + * disappear, then deletes the objects. The content will become visible. + * + * @param obj The pager object + * @param content The object to show + * + * @ingroup Pager + */ +EAPI void +elm_pager_to_content_pop(Evas_Object *obj, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *ll; + Item *it; + if (!wd) return; + if (!wd->stack) return; + it = eina_list_last(wd->stack)->data; + it->popme = EINA_TRUE; + ll = eina_list_last(wd->stack); + if (ll) + { + EINA_LIST_FOREACH(wd->stack, ll, it) + { + if (it->content == content) + { + ll = eina_list_last(wd->stack); + while (ll = ll->prev) + { + if (ll->data == it) break; + else + { + Item *itdel = ll->data; + evas_object_del(itdel->content); + } + } + elm_pager_content_promote(obj, content); + return; + } + } + } +} + +/** * Promote an object already in the pager stack to the top of the stack * * This will take the indicated object and promote it to the top of the stack -- 2.7.4