X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flib%2Felm_toolbar.c;h=75a20939108525c3ab1142af499c5d95d2ec5495;hb=b29b8c00a17f3a5d35c152bac83c422b33844534;hp=bd2e094d5b1452d1d152c60aaa4264201905c293;hpb=40ee7022a3f88f9271afc97104e80b3356f333ad;p=framework%2Fuifw%2Felementary.git diff --git a/src/lib/elm_toolbar.c b/src/lib/elm_toolbar.c index bd2e094..75a2093 100644 --- a/src/lib/elm_toolbar.c +++ b/src/lib/elm_toolbar.c @@ -9,7 +9,7 @@ typedef struct _Elm_Toolbar_Item Elm_Toolbar_Item; struct _Widget_Data { - Evas_Object *scr, *bx; + Evas_Object *scr, *bx, *more, *bx_more, *bx_more2; Evas_Object *menu_parent; Eina_Inlist *items; Elm_Toolbar_Item *more_item, *selected_item; @@ -17,6 +17,7 @@ struct _Widget_Data Elm_Icon_Lookup_Order lookup_order; int icon_size; unsigned int item_count; + unsigned int item_max; double align; Elm_Object_Select_Mode select_mode; Eina_Bool homogeneous : 1; @@ -35,11 +36,13 @@ struct _Elm_Toolbar_Item Evas_Object *icon; Evas_Object *object; Evas_Object *o_menu; + Evas_Object *in_box; Evas_Smart_Cb func; - struct { - int priority; - Eina_Bool visible : 1; - } prio; + struct + { + int priority; + Eina_Bool visible : 1; + } prio; Eina_Bool selected : 1; Eina_Bool separator : 1; Eina_Bool menu : 1; @@ -168,17 +171,26 @@ _item_select(Elm_Toolbar_Item *it) Widget_Data *wd = elm_widget_data_get(WIDGET(it)); Evas_Object *obj2; Eina_Bool sel; + Evas_Coord w, h; if (!wd) return; if (elm_widget_item_disabled_get(it) || (it->separator) || (it->object)) return; sel = it->selected; + evas_object_geometry_get(it->object, NULL, NULL, &w, &h); + if (wd->select_mode != ELM_OBJECT_SELECT_MODE_NONE) { if (sel) { - if (wd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) return; - _item_unselect(it); + if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND) + if (wd->more_item == it) + { + edje_object_signal_emit(elm_layout_edje_get(wd->more), "elm,state,close", "elm"); + _item_unselect(it); + } + if (wd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) + _item_unselect(it); } else { @@ -188,6 +200,30 @@ _item_select(Elm_Toolbar_Item *it) it->selected = EINA_TRUE; wd->selected_item = it; + if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND) + { + if (wd->more_item == it) + { + if (!evas_object_box_children_get(wd->bx_more2)) + edje_object_signal_emit(elm_layout_edje_get(wd->more), "elm,state,open", "elm"); + else + edje_object_signal_emit(elm_layout_edje_get(wd->more), "elm,state,open2", "elm"); + } + else + { + if (it->in_box != wd->bx) + { + edje_object_signal_emit(wd->VIEW(more_item), "elm,state,selected", "elm"); + elm_widget_signal_emit(wd->more_item->icon, "elm,state,selected", "elm"); + } + else + { + edje_object_signal_emit(wd->VIEW(more_item), "elm,state,unselected", "elm"); + elm_widget_signal_emit(wd->more_item->icon, "elm,state,unselected", "elm"); + } + edje_object_signal_emit(elm_layout_edje_get(wd->more), "elm,state,close", "elm"); + } + } edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm"); elm_widget_signal_emit(it->icon, "elm,state,selected", "elm"); _item_show(it); @@ -267,7 +303,7 @@ _del_pre_hook(Evas_Object *obj) if (!wd) return; it = ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items); - while(it) + while (it) { next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next); _item_del(it); @@ -335,7 +371,7 @@ _theme_hook_item(Evas_Object *obj, Elm_Toolbar_Item *it, double scale, int icon_ evas_object_size_hint_max_set(it->icon, ms, ms); edje_object_part_swallow(view, "elm.swallow.icon", it->icon); } - edje_object_part_text_set(view, "elm.text", it->label); + edje_object_part_text_escaped_set(view, "elm.text", it->label); } else { @@ -430,10 +466,14 @@ _item_content_set_hook(Elm_Object_Item *it, Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it; Evas_Object *obj = WIDGET(item); Widget_Data *wd = elm_widget_data_get(obj); - + if (!wd || !obj) return; if (item->object == content) return; + + if (item->object) evas_object_del(item->object); + item->object = content; - elm_widget_sub_object_add(obj, item->object); + if (item->object) + elm_widget_sub_object_add(obj, item->object); scale = (elm_widget_scale_get(obj) * _elm_config->scale); _theme_hook_item(obj, item, scale, wd->icon_size); } @@ -532,6 +572,7 @@ _sizing_eval(Evas_Object *obj) // minh = minh + (h - vh); } evas_object_resize(wd->bx, minw_bx, minh_bx); + evas_object_resize(wd->more, w, h); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, -1, -1); } @@ -569,13 +610,16 @@ _toolbar_item_prio_compare_cb(const void *i1, const void *i2) if (!eti2) return 1; if (!eti1) return -1; + if (eti2->prio.priority == eti1->prio.priority) + return -1; + return eti2->prio.priority - eti1->prio.priority; } static void _fix_items_visibility(Widget_Data *wd, Evas_Coord *iw, Evas_Coord vw) { - Elm_Toolbar_Item *it; + Elm_Toolbar_Item *it, *prev; Eina_List *sorted = NULL; Evas_Coord ciw = 0, cih = 0; @@ -596,7 +640,70 @@ _fix_items_visibility(Widget_Data *wd, Evas_Coord *iw, Evas_Coord vw) evas_object_geometry_get(VIEW(it), NULL, NULL, &ciw, &cih); if (wd->vertical) *iw += cih; else *iw += ciw; - it->prio.visible = (*iw <= vw); + if (!it->separator) + it->prio.visible = (*iw <= vw); + else + { + prev = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev); + it->prio.visible = prev->prio.visible; + } + } +} + +static void +_fix_items_visibility_by_number(Widget_Data *wd, unsigned int *count) +{ + Elm_Toolbar_Item *it, *prev, *next, *max = NULL; + Eina_List *sorted = NULL; + *count = 0; + + EINA_INLIST_FOREACH(wd->items, it) + { + if (it->separator) + { + prev = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev); + it->prio.priority = prev->prio.priority; + } + } + + EINA_INLIST_FOREACH(wd->items, it) + { + sorted = eina_list_sorted_insert(sorted, + _toolbar_item_prio_compare_cb, it); + } + + EINA_LIST_FREE(sorted, it) + { + *count += 1; + if(*count <= wd->item_max) + { + it->prio.visible = EINA_TRUE; + it->in_box = wd->bx; + if (*count == wd->item_max) + max = it; + } + else + { + it->prio.visible = EINA_FALSE; + if (wd->item_count < (wd->item_max * 2) || + *count <= (wd->item_count + wd->item_max) / 2) + it->in_box = wd->bx_more; + else + it->in_box = wd->bx_more2; + + if (max) + { + max->prio.visible = EINA_FALSE; + max->in_box = wd->bx_more; + next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(max)->next); + if (next && next->separator) + { + next->prio.visible = max->prio.visible; + next->in_box = max->in_box; + } + max = NULL; + } + } } } @@ -614,6 +721,7 @@ _resize_job(void *data) Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord mw, mh, vw = 0, vh = 0, w = 0, h = 0; Elm_Toolbar_Item *it; + Eina_List *list; if (!wd) return; wd->resize_job = NULL; @@ -737,12 +845,33 @@ _resize_job(void *data) } else if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND) { + unsigned int count; if ((vw >= mw) && (vh >= mh)) evas_object_resize(wd->bx, vw, vh); else if (vw < mw) evas_object_resize(wd->bx, mw, vh); else if (vh < mh) evas_object_resize(wd->bx, vw, mh); + _fix_items_visibility_by_number(wd, &count); + + evas_object_box_remove_all(wd->bx, EINA_FALSE); + evas_object_box_remove_all(wd->bx_more, EINA_FALSE); + evas_object_box_remove_all(wd->bx_more2, EINA_FALSE); + EINA_INLIST_FOREACH(wd->items, it) + { + if (it->in_box) + { + evas_object_box_append(it->in_box, VIEW(it)); + evas_object_show(VIEW(it)); + } + } + if (count > wd->item_max) + { + evas_object_box_append(wd->bx, wd->VIEW(more_item)); + evas_object_show(wd->VIEW(more_item)); + } + else + evas_object_hide(wd->VIEW(more_item)); } else { @@ -764,6 +893,28 @@ _resize_job(void *data) } } + // Remove the first or last separator since it is not neccessary + list = evas_object_box_children_get(wd->bx_more); + EINA_INLIST_FOREACH(wd->items, it) + { + if (it->separator && ((VIEW(it) == eina_list_data_get(list)) || + (VIEW(it) == eina_list_nth(list, eina_list_count(list)-1)))) + { + evas_object_box_remove(wd->bx_more, VIEW(it)); + evas_object_hide(VIEW(it)); + } + } + list = evas_object_box_children_get(wd->bx_more2); + EINA_INLIST_FOREACH(wd->items, it) + { + if (it->separator && ((VIEW(it) == eina_list_data_get(list)) || + (VIEW(it) == eina_list_nth(list, eina_list_count(list)-1)))) + { + evas_object_box_remove(wd->bx_more2, VIEW(it)); + evas_object_hide(VIEW(it)); + } + } + _mirrored_set(obj, elm_widget_mirrored_get(obj)); } @@ -778,11 +929,23 @@ static void _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { Widget_Data *wd = elm_widget_data_get(data); + Evas_Coord x, y, h; + evas_object_geometry_get(data, &x, &y, NULL, &h); + evas_object_move(wd->more, x, y + h); if (!wd->resize_job) wd->resize_job = ecore_job_add(_resize_job, data); } static void +_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + Evas_Coord x, y, h; + evas_object_geometry_get(data, &x, &y, NULL, &h); + evas_object_move(wd->more, x, y + h); +} + +static void _select_filter(Elm_Toolbar_Item *it, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__) { int button; @@ -1002,7 +1165,7 @@ _item_new(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb f } if (it->label) { - edje_object_part_text_set(VIEW(it), "elm.text", it->label); + edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label); edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm"); } mw = mh = -1; @@ -1033,7 +1196,6 @@ _item_new(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb f _resize_item, obj); if ((!wd->items) && (wd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS)) _item_select(it); - wd->item_count++; return it; } @@ -1042,7 +1204,7 @@ _elm_toolbar_item_label_update(Elm_Toolbar_Item *item) { Evas_Coord mw = -1, mh = -1; Widget_Data *wd = elm_widget_data_get(WIDGET(item)); - edje_object_part_text_set(VIEW(item), "elm.text", item->label); + edje_object_part_text_escaped_set(VIEW(item), "elm.text", item->label); edje_object_signal_emit(VIEW(item), "elm,state,text,visible", "elm"); elm_coords_finger_size_adjust(1, &mw, 1, &mh); @@ -1090,7 +1252,7 @@ _item_label_set(Elm_Toolbar_Item *item, const char *label, const char *sig) s = edje_object_data_get(VIEW(item), "transition_animation_on"); if ((s) && (atoi(s))) { - edje_object_part_text_set(VIEW(item), "elm.text_new", item->label); + edje_object_part_text_escaped_set(VIEW(item), "elm.text_new", item->label); edje_object_signal_emit (VIEW(item), sig, "elm"); edje_object_signal_callback_add(VIEW(item), "elm,state,label_set,done", "elm", @@ -1241,9 +1403,11 @@ elm_toolbar_add(Evas_Object *parent) elm_widget_del_hook_set(obj, _del_hook); elm_widget_theme_hook_set(obj, _theme_hook); elm_widget_translate_hook_set(obj, _translate_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); wd->more_item = NULL; wd->selected_item = NULL; + wd->item_max = 9999; wd->scr = elm_smart_scroller_add(e); elm_smart_scroller_widget_set(wd->scr, obj); elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", "default"); @@ -1255,7 +1419,6 @@ elm_toolbar_add(Evas_Object *parent) ELM_SMART_SCROLLER_POLICY_AUTO, ELM_SMART_SCROLLER_POLICY_OFF); - wd->icon_size = _elm_toolbar_icon_size_get(wd); @@ -1269,8 +1432,28 @@ elm_toolbar_add(Evas_Object *parent) elm_smart_scroller_child_set(wd->scr, wd->bx); evas_object_show(wd->bx); + wd->more = elm_layout_add(obj); + elm_layout_theme_set(wd->more, "toolbar", "more", "default"); + elm_widget_sub_object_add(obj, wd->more); + evas_object_show(wd->more); + + wd->bx_more = evas_object_box_add(e); + evas_object_size_hint_align_set(wd->bx_more, wd->align, 0.5); + evas_object_box_layout_set(wd->bx_more, _layout, obj, NULL); + elm_widget_sub_object_add(obj, wd->bx_more); + elm_object_part_content_set(wd->more, "elm.swallow.content", wd->bx_more); + evas_object_show(wd->bx_more); + + wd->bx_more2 = evas_object_box_add(e); + evas_object_size_hint_align_set(wd->bx_more2, wd->align, 0.5); + evas_object_box_layout_set(wd->bx_more2, _layout, obj, NULL); + elm_widget_sub_object_add(obj, wd->bx_more2); + elm_object_part_content_set(wd->more, "elm.swallow.content2", wd->bx_more2); + evas_object_show(wd->bx_more2); + elm_toolbar_shrink_mode_set(obj, _elm_config->toolbar_shrink_mode); evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE, _resize, obj); + evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_MOVE, _move, obj); evas_object_event_callback_add(wd->bx, EVAS_CALLBACK_RESIZE, _resize, obj); elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO); @@ -1317,6 +1500,7 @@ elm_toolbar_item_append(Evas_Object *obj, const char *icon, const char *label, E _theme_hook_item(obj, it, scale, wd->icon_size); _sizing_eval(obj); + wd->item_count++; return (Elm_Object_Item *)it; } @@ -1337,6 +1521,7 @@ elm_toolbar_item_prepend(Evas_Object *obj, const char *icon, const char *label, evas_object_show(VIEW(it)); _theme_hook_item(obj, it, scale, wd->icon_size); _sizing_eval(obj); + wd->item_count++; return (Elm_Object_Item *)it; } @@ -1362,6 +1547,7 @@ elm_toolbar_item_insert_before(Evas_Object *obj, Elm_Object_Item *before, const evas_object_show(VIEW(it)); _theme_hook_item(obj, it, scale, wd->icon_size); _sizing_eval(obj); + wd->item_count++; return (Elm_Object_Item *)it; } @@ -1387,6 +1573,7 @@ elm_toolbar_item_insert_after(Evas_Object *obj, Elm_Object_Item *after, const ch evas_object_show(VIEW(it)); _theme_hook_item(obj, it, scale, wd->icon_size); _sizing_eval(obj); + wd->item_count++; return (Elm_Object_Item *)it; } @@ -1487,6 +1674,15 @@ elm_toolbar_selected_item_get(const Evas_Object *obj) return (Elm_Object_Item *) wd->selected_item; } +EAPI Elm_Object_Item * +elm_toolbar_more_item_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return (Elm_Object_Item *) wd->more_item; +} + EAPI void elm_toolbar_item_icon_set(Elm_Object_Item *it, const char *icon) { @@ -1661,6 +1857,12 @@ elm_toolbar_shrink_mode_set(Evas_Object *obj, Elm_Toolbar_Shrink_Mode shrink_mod else if (shrink_mode == ELM_TOOLBAR_SHRINK_HIDE) elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF, ELM_SMART_SCROLLER_POLICY_OFF); + else if (shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND) + { + elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_AUTO, + ELM_SMART_SCROLLER_POLICY_OFF); + wd->more_item = _item_new(obj, "more_menu", "More", NULL, NULL); + } else elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_AUTO, ELM_SMART_SCROLLER_POLICY_OFF); @@ -2040,6 +2242,24 @@ elm_toolbar_items_count(const Evas_Object *obj) } EAPI void +elm_toolbar_items_max_set(Evas_Object *obj, unsigned int max) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->item_max = max; +} + +EAPI unsigned int +elm_toolbar_items_max_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->item_max; +} + +EAPI void elm_toolbar_select_mode_set(Evas_Object *obj, Elm_Object_Select_Mode mode) { ELM_CHECK_WIDTYPE(obj, widtype);