/* * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "i18n.h" #include "bar.h" #include "engine.h" #include "defs.h" #include "dbg.h" enum _hbar_state { HBAR_STATE_HIDE, HBAR_STATE_HBAR, HBAR_STATE_UBAR, HBAR_STATE_DBAR }; struct _hbar_item; struct _hbar_data { Evas_Object *ly; Evas_Object *scr; Evas_Object *bx; Eina_List *list; struct _hbar_item *cur; enum _hbar_state state; struct bar_info *ubar; }; struct _hbar_item { Evas_Object *eo; struct engine_bar_item *it; struct _hbar_data *bar; Eina_Bool dirty; struct bar_info *dbar; }; static int _is_next_object(Evas_Object *target, Evas_Object *from) { Evas_Coord y1, y2; if (!target || !from) { _ERR("Invalide argument"); return -1; } evas_object_geometry_get(target, NULL, &y1, NULL, NULL); evas_object_geometry_get(from, NULL, &y2, NULL, NULL); return y2 < y1; } static int _get_effect_direction(Evas_Object *target, Evas_Object *from) { Evas_Coord x1, y1, x2, y2; evas_object_geometry_get(target, &x1, &y1, NULL, NULL); evas_object_geometry_get(from, &x2, &y2, NULL, NULL); if (y2 == y1) { if (x1 > x2) return BAR_DIR_RIGHT; else return BAR_DIR_LEFT; } else if (y2 < y1) { return BAR_DIR_DOWN; } else { return BAR_DIR_UP; } } static void _set_effect(Evas_Object *target, Evas_Object *from, int dir) { const char *t_sig, *f_sig; switch (dir) { case BAR_DIR_RIGHT: t_sig = SIG_FOCUS_FROM_LEFT; f_sig = SIG_UNFOCUS_TO_RIGHT; break; case BAR_DIR_LEFT: t_sig = SIG_FOCUS_FROM_RIGHT; f_sig = SIG_UNFOCUS_TO_LEFT; break; case BAR_DIR_UP: t_sig = SIG_FOCUS_FROM_DOWN; f_sig = SIG_UNFOCUS_TO_UP; break; case BAR_DIR_DOWN: t_sig = SIG_FOCUS_FROM_UP; f_sig = SIG_UNFOCUS_TO_DOWN; break; default: return; } elm_object_signal_emit(target, t_sig, SRC_PROG); elm_object_signal_emit(from, f_sig, SRC_PROG); } static inline Evas_Object *_get_bar_object(struct bar_info *bar) { if (!bar) return NULL; return bar->ops->get_object(bar); } static inline Evas_Object *_get_item_object(struct bar_info *bar) { if (!bar) return NULL; return bar->ops->get_item(bar); } static void _update_child_bar(struct _hbar_data *, struct _hbar_item *); static void _focused(void *data, Evas_Object *obj, void *ei) { struct _hbar_item *foc; struct _hbar_item *cur; struct _hbar_data *bar; Evas_Object *eo; int next; if (!data) { _ERR("Invalid argument"); return; } foc = data; bar = foc->bar; if (!bar) { _ERR("bar is NULL"); return; } cur = bar->cur; switch (bar->state) { case HBAR_STATE_DBAR: if (!cur) { elm_object_signal_emit(foc->eo, SIG_INITIAL_FOCUS, SRC_PROG); } else { elm_object_signal_emit(foc->eo, SIG_FOCUS, SRC_PROG); if (cur != foc) { elm_object_signal_emit(cur->eo, SIG_HIDE, SRC_PROG); } eo = _get_item_object(cur->dbar); if (eo) { elm_object_signal_emit(eo, SIG_UNFOCUS_TO_HBAR, SRC_PROG); } } break; case HBAR_STATE_HBAR: if (!cur) { elm_object_signal_emit(foc->eo, SIG_INITIAL_FOCUS, SRC_PROG); } else if (cur == foc) { elm_object_signal_emit(foc->eo, SIG_FOCUS, SRC_PROG); } else { next = _is_next_object(foc->eo, cur->eo); if (next < 0) break; elm_object_signal_emit(foc->eo, next ? SIG_FOCUS_FROM_UP : SIG_FOCUS_FROM_DOWN, SRC_PROG); elm_object_signal_emit(cur->eo, next ? SIG_UNFOCUS_TO_DOWN : SIG_UNFOCUS_TO_UP, SRC_PROG); } break; case HBAR_STATE_UBAR: elm_object_signal_emit(foc->eo, SIG_FOCUS_FROM_UP, SRC_PROG); eo = _get_item_object(bar->ubar); if (eo) { elm_object_signal_emit(eo, SIG_UNFOCUS, SRC_PROG); } bar->ubar->ops->hide(bar->ubar); elm_object_signal_emit(bar->ly, SIG_SHOW_DBAR, SRC_PROG); elm_object_signal_emit(bar->ly, SIG_HIDE_UBAR, SRC_PROG); break; case HBAR_STATE_HIDE: elm_object_signal_emit(foc->eo, SIG_INITIAL_FOCUS, SRC_PROG); break; } bar->cur = foc; bar->state = HBAR_STATE_HBAR; _update_child_bar(bar, foc); } static Eina_Bool _ubar_focused(void *data, Evas_Object *foc) { struct _hbar_data *bar; struct bar_info *ubar; struct bar_info *dbar; Evas_Object *eo; Evas_Object *cur; if (!data || !foc) { _ERR("Invalid argument"); return EINA_FALSE; } bar = data; if (!bar) { _ERR("bar is NULL"); return EINA_FALSE; } if (!bar->cur) { _ERR("current item is NULL"); return EINA_FALSE; } ubar = bar->ubar; dbar = bar->cur->dbar; cur = _get_item_object(ubar); if (!cur) return EINA_FALSE; switch (bar->state) { case HBAR_STATE_DBAR: eo = _get_item_object(dbar); if (eo) { elm_object_signal_emit(eo, SIG_UNFOCUS_TO_HBAR, SRC_PROG); } /* fallthrough */ case HBAR_STATE_HBAR: elm_object_signal_emit(bar->cur->eo, SIG_FOCUS, SRC_PROG); elm_object_signal_emit(bar->cur->eo, SIG_UNFOCUS_TO_UP, SRC_PROG); elm_object_signal_emit(bar->ly, SIG_SHOW_UBAR, SRC_PROG); elm_object_signal_emit(bar->ly, SIG_HIDE_DBAR, SRC_PROG); dbar->ops->hide(dbar); break; case HBAR_STATE_UBAR: elm_object_signal_emit(foc, SIG_FOCUS, SRC_PROG); if (cur != foc) elm_object_signal_emit(cur, SIG_UNFOCUS, SRC_PROG); break; default: break; } bar->state = HBAR_STATE_UBAR; return EINA_TRUE; } static Eina_Bool _dbar_focused(void *data, Evas_Object *foc) { struct _hbar_data *bar; struct bar_info *dbar; Evas_Object *cur; int dir; Eina_Bool r; if (!data || !foc) { _ERR("Invalide argument"); return EINA_FALSE; } r = EINA_FALSE; bar = data; if (!bar) { _ERR("bar is NULL"); return EINA_FALSE; } dbar = bar->cur->dbar; cur = _get_item_object(dbar); if (!cur) return EINA_FALSE; switch (bar->state) { case HBAR_STATE_HBAR: case HBAR_STATE_HIDE: elm_object_signal_emit(foc, SIG_INITIAL_FOCUS, SRC_PROG); elm_object_signal_emit(bar->cur->eo, SIG_UNFOCUS_TO_DBAR, SRC_PROG); break; case HBAR_STATE_DBAR: if (cur == foc) { elm_object_signal_emit(foc, SIG_INITIAL_FOCUS, SRC_PROG); } else { dir = _get_effect_direction(foc, cur); _set_effect(foc, cur, dir); } r = EINA_TRUE; break; case HBAR_STATE_UBAR: return EINA_TRUE; default: break; } bar->state = HBAR_STATE_DBAR; return r; } static void _mouse_over(void *data, Evas *e, Evas_Object *obj, void *ei) { struct _hbar_item *item; if (!data) { _ERR("Invalide argument"); return; } item = data; if (elm_object_focus_get(item->eo)) return; elm_object_focus_set(item->eo, EINA_TRUE); } static void _clicked(void *data, Evas *e, Evas_Object *obj, void *ei) { struct _hbar_item *item; Evas_Event_Mouse_Up *ev; Evas_Coord x, y, w, h; if (!data || !ei) return; ev = ei; evas_object_geometry_get(obj, &x, &y, &w, &h); if (ev->canvas.x < x || ev->canvas.x > x + w || ev->canvas.y < y || ev->canvas.y > y + h) return; item = data; engine_bar_item_launch(item->it); } static int _launch_app(struct bar_info *info) { struct _hbar_data *bar; struct _hbar_item *item; if (!info) return EINA_FALSE; bar = info->data; item = bar->cur; if (!item) { _ERR("Invalid argument"); return -1; } return engine_bar_item_launch(item->it); } static Eina_Bool _move(struct bar_info *info) { struct _hbar_data *bar; struct _hbar_item *item; Eina_List *l; if (!info || !info->data) { _ERR("Invalid argument"); return EINA_FALSE; } bar = info->data; item = bar->cur; if (!item) { EINA_LIST_FOREACH(bar->list, l, item) { if (elm_object_focus_allow_get(item->eo)) break; } if (!item) return EINA_FALSE; } elm_object_focus_set(item->eo, EINA_TRUE); return EINA_TRUE; } static Eina_Bool _is_move(struct bar_info *info, int dir) { struct _hbar_data *bar; if (!info) { _ERR("Inavlid argument"); return EINA_FALSE; } bar = info->data; switch (dir) { case BAR_DIR_UP: if (eina_list_data_get(bar->list) == bar->cur) return EINA_TRUE; default: return EINA_FALSE; } return EINA_FALSE; } static enum bar_event _move_right(struct bar_info *info) { struct _hbar_item *item; struct _hbar_data *bar; Eina_Bool r; if (!info || !info->data) return BAR_EVENT_ERROR; bar = info->data; item = bar->cur; if (!item) return BAR_EVENT_ERROR; switch (bar->state) { case HBAR_STATE_HBAR: r = item->dbar->ops->move(item->dbar); break; case HBAR_STATE_DBAR: r = item->dbar->ops->is_move(item->dbar, BAR_DIR_RIGHT); break; default: return BAR_EVENT_ERROR; } return r ? BAR_EVENT_DONE : BAR_EVENT_PASS; } static enum bar_event _move_left(struct bar_info *info) { struct _hbar_item *item; struct _hbar_data *bar; Eina_Bool r; if (!info || !info->data) return BAR_EVENT_ERROR; bar = info->data; item = bar->cur; if (!item) return BAR_EVENT_ERROR; switch (bar->state) { case HBAR_STATE_DBAR: if (!item->dbar->ops->is_move(item->dbar, BAR_DIR_LEFT)) return BAR_EVENT_PASS; r = _move(info); break; case HBAR_STATE_HBAR: return BAR_EVENT_MOVE; case HBAR_STATE_UBAR: if (!bar->ubar->ops->is_move(bar->ubar, BAR_DIR_LEFT)) return BAR_EVENT_PASS; return BAR_EVENT_MOVE; default: return BAR_EVENT_ERROR; } return r ? BAR_EVENT_DONE : BAR_EVENT_PASS; } static enum bar_event _move_up(struct bar_info *info) { struct _hbar_data *bar; Eina_Bool r; if (!info || !info->data) return BAR_EVENT_ERROR; bar = info->data; switch (bar->state) { case HBAR_STATE_HBAR: if (!_is_move(info, BAR_DIR_UP)) return BAR_EVENT_PASS; r = bar->ubar->ops->move(bar->ubar); break; default: r = EINA_FALSE; break; } return r ? BAR_EVENT_DONE : BAR_EVENT_PASS; } static enum bar_event _move_down(struct bar_info *info) { struct _hbar_data *bar; Eina_Bool r; if (!info || !info->data) return BAR_EVENT_ERROR; bar = info->data; switch (bar->state) { case HBAR_STATE_UBAR: if (!bar->ubar->ops->is_move(bar->ubar, BAR_DIR_DOWN)) return BAR_EVENT_PASS; bar->cur = eina_list_data_get(bar->list); r = _move(info); elm_object_signal_emit(bar->ly, SIG_SHOW_DBAR, SRC_PROG); break; default: r = EINA_FALSE; break; } return r ? BAR_EVENT_DONE : BAR_EVENT_PASS; } static enum bar_event _back(struct bar_info *info) { struct _hbar_item *item; struct _hbar_data *bar; Eina_Bool r; if (!info || !info->data) return BAR_EVENT_ERROR; bar = info->data; item = bar->cur; if (!item) return BAR_EVENT_ERROR; switch (bar->state) { case HBAR_STATE_HBAR: return BAR_EVENT_BACK; case HBAR_STATE_DBAR: r = _move(info); break; case HBAR_STATE_UBAR: default: return BAR_EVENT_ERROR; } return r ? BAR_EVENT_DONE : BAR_EVENT_PASS; } static enum bar_event _enter(struct bar_info *info) { struct _hbar_data *bar; struct _hbar_item *item; Eina_Bool r; if (!info || !info->data) return BAR_EVENT_ERROR; bar = info->data; item = bar->cur; if (!item) return BAR_EVENT_ERROR; switch (bar->state) { case HBAR_STATE_HBAR: r = _launch_app(info); break; case HBAR_STATE_UBAR: case HBAR_STATE_DBAR: default: return BAR_EVENT_ERROR; } return r ? BAR_EVENT_DONE : BAR_EVENT_PASS; } static enum bar_event _key_event(struct bar_info *info, void *ei) { Ecore_Event_Key *ev; enum bar_event r; if (!info || !ei) return BAR_EVENT_ERROR; ev = ei; if (!strcmp(ev->keyname, KEY_BACK)) r = _back(info); else if (!strcmp(ev->keyname, KEY_ENTER)) r = _enter(info); else if (!strcmp(ev->keyname, KEY_RIGHT)) r = _move_right(info); else if (!strcmp(ev->keyname, KEY_LEFT)) r = _move_left(info); else if (!strcmp(ev->keyname, KEY_UP)) r = _move_up(info); else if (!strcmp(ev->keyname, KEY_DOWN)) r = _move_down(info); else r = BAR_EVENT_PASS; return r; } static enum bar_event _bar_event(struct bar_info *info, void *ei, enum bar_event ev) { struct _hbar_data *bar; enum bar_event r; if (!info || !ei) return BAR_EVENT_ERROR; bar = info->data; switch (ev) { case BAR_EVENT_DONE: case BAR_EVENT_ERROR: return ev; case BAR_EVENT_PASS: r = _key_event(info, ei); break; case BAR_EVENT_MOVE: if (bar->state == HBAR_STATE_UBAR) { bar->cur = eina_list_data_get(bar->list); _move(info); elm_object_signal_emit(bar->ly, SIG_SHOW_DBAR, SRC_PROG); } else if (bar->state == HBAR_STATE_DBAR) { _move(info); } r = BAR_EVENT_DONE; break; default: r = BAR_EVENT_PASS; break; } return r; } static enum bar_event _key_up(struct bar_info *info, void *ei) { struct _hbar_data *bar; enum bar_event r; if (!info || !ei) return BAR_EVENT_ERROR; bar = info->data; switch (bar->state) { case HBAR_STATE_UBAR: r = bar->ubar->ops->key_up(bar->ubar, ei); break; default: return BAR_EVENT_DONE; } return _bar_event(info, ei, r); } static enum bar_event _key_down(struct bar_info *info, void *ei) { struct _hbar_data *bar; struct _hbar_item *item; enum bar_event r; if (!info || !ei) return BAR_EVENT_ERROR; bar = info->data; item = bar->cur; if (!item) return BAR_EVENT_ERROR; switch (bar->state) { case HBAR_STATE_HBAR: r = BAR_EVENT_PASS; break; case HBAR_STATE_UBAR: r = bar->ubar->ops->key_down(bar->ubar, ei); break; case HBAR_STATE_DBAR: r = item->dbar->ops->key_down(item->dbar, ei); break; default: return BAR_EVENT_ERROR; } return _bar_event(info, ei, r); } static inline Evas_Object *_add_hbar_item_bg(Evas_Object *base, struct engine_bar_item *it) { Evas_Object *bg; int r, g, b; if (!base || !it) return NULL; bg = evas_object_rectangle_add(evas_object_evas_get(base)); if (!bg) { _ERR("bg add failed"); return NULL; } r = 128; g = 128; b = 128; engine_bar_item_get_color(it, &r, &g, &b); evas_object_color_set(bg, r, g, b, 255); return bg; } static inline Evas_Object *_add_icon(Evas_Object *base, const char *file) { Evas_Object *ic; if (!base || !file) return NULL; ic = elm_icon_add(base); if (!ic) { _ERR("icon add failed"); return NULL; } elm_image_file_set(ic, file, NULL); return ic; } static int _add_ubar(struct _hbar_data *bar, Evas_Object *base) { struct bar_info *ubar; int r; if (!bar || !base) { _ERR("Invalid argument"); return -1; } ubar = calloc(1, sizeof(*ubar)); if (!ubar) { _ERR("calloc failed"); return -1; } ubar->cb.func = _ubar_focused; ubar->cb.data = bar; bar->ubar = ubar; r = init_user_bar(ubar); if (r < 0) { free(ubar); return -1; } r = bar->ubar->ops->add_bar(bar->ubar, bar->ly); if (r < 0) { free(ubar); return -1; } return 0; } static int _add_bar(struct bar_info *info, Evas_Object *base) { Evas_Object *scr, *bx; struct _hbar_data *bar; int r; if (!base || !info || !info->data) { _ERR("Invalid argument"); return -1; } bar = info->data; scr = elm_scroller_add(base); if (!scr) { _ERR("scroller add failed"); return -1; } elm_scroller_policy_set(scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); bx = elm_box_add(scr); if (!bx) { _ERR("box add failed"); evas_object_del(scr); return -1; } evas_object_show(bx); elm_object_content_set(scr, bx); elm_object_part_content_set(base, PART_HOMEBAR, scr); bar->ly = base; bar->scr = scr; bar->bx = bx; r = _add_ubar(bar, base); if (r < 0) { evas_object_del(scr); return -1; } return 0; } static void _lbl_start_slide(void *data, Evas_Object *obj, void *ei) { elm_label_ellipsis_set(data, EINA_FALSE); elm_label_slide_mode_set(data, ELM_LABEL_SLIDE_MODE_AUTO); elm_label_slide_go(data); } static void _lbl_stop_slide(void *data, Evas_Object *obj, void *ei) { elm_label_ellipsis_set(data, EINA_TRUE); elm_label_slide_mode_set(data, ELM_LABEL_SLIDE_MODE_NONE); elm_label_slide_go(data); } static Evas_Object *_add_label(Evas_Object *ly, const char *name) { Evas_Object *lbl; const char *s; if (!ly || !name) { _ERR("Invalid argument"); return NULL; } lbl = elm_label_add(ly); if (!lbl) { _ERR("failed to add label"); return NULL; } elm_object_style_set(lbl, STYLE_LABEL_SLIDE_CENTER); s = edje_object_data_get(elm_layout_edje_get(ly), DATA_TITLE_WIDTH); if (s) elm_label_wrap_width_set(lbl, atoi(s)); else _ERR("No title width exist"); elm_object_text_set(lbl, name); elm_label_slide_speed_set(lbl, LABEL_SLIDE_SPEED); evas_object_smart_callback_add(ly, "focused", _lbl_start_slide, lbl); evas_object_smart_callback_add(ly, "unfocused", _lbl_stop_slide, lbl); return lbl; } static Evas_Object *_new_hbar_item(Evas_Object *p, struct _hbar_item *item, struct engine_bar_item *it) { Evas_Object *ly, *eo, *lbl; if (!p || !it || !item) { _ERR("Invalid argument"); return NULL; } ly = elm_layout_add(p); if (!ly) { _ERR("layout add failed"); return NULL; } elm_layout_file_set(ly, EDJEFILE, GRP_HOMEBAR_ITEM); eo = _add_hbar_item_bg(ly, it); if (!eo) goto err; elm_object_part_content_set(ly, PART_BG, eo); eo = _add_hbar_item_bg(ly, it); if (!eo) goto err; elm_object_part_content_set(ly, PART_BG2, eo); eo = _add_icon(ly, engine_bar_item_get_icon(it)); if (!eo) goto err; elm_object_part_content_set(ly, PART_ICON, eo); eo = _add_icon(ly, engine_bar_item_get_icon_focus(it)); if (!eo) goto err; elm_object_part_content_set(ly, PART_ICON_FOCUS, eo); lbl = _add_label(ly, engine_bar_item_get_name(it)); if (!lbl) goto err; elm_object_part_content_set(ly, PART_NAME, lbl); evas_object_show(ly); elm_object_focus_allow_set(ly, EINA_TRUE); evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_MOVE, _mouse_over, item); evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_UP, _clicked, item); evas_object_smart_callback_add(ly, "focused", _focused, item); return ly; err: evas_object_del(ly); return NULL; } static int _init_child_bar(struct _hbar_item *item) { struct bar_info *dbar; int r; dbar = calloc(1, sizeof(*dbar)); if (!dbar) goto err; dbar->cb.func = _dbar_focused; dbar->cb.data = item->bar; r = init_dynamic_bar(dbar); if (r < 0) goto dbar_err; item->dbar = dbar; return 0; dbar_err: free(dbar); dbar = NULL; err: return -1; } static struct _hbar_item *_pack_item(struct _hbar_data *bar, struct engine_bar_item *it) { Evas_Object *base; struct _hbar_item *item; int r; if (!bar || !it) return NULL; item = calloc(1, sizeof(*item)); if (!item) { _ERR("calloc failed"); return NULL; } base = _new_hbar_item(bar->bx, item, it); if (!base) { free(item); return NULL; } elm_box_pack_end(bar->bx, base); item->eo = base; item->bar = bar; item->it = it; r = _init_child_bar(item); if (r < 0) goto err; r = item->dbar->ops->add_bar(item->dbar, bar->ly); if (r < 0) goto err2; item->dirty = EINA_TRUE; return item; err2: item->dbar->ops->release(item->dbar); err: evas_object_del(base); free(item); return NULL; } static void _update_child_bar(struct _hbar_data *bar, struct _hbar_item *item) { struct _hbar_item *_item; Eina_List *l; Evas_Object *dbar; Evas_Object *_dbar; if (!bar || !item) { _ERR("Invalid argument"); return; } if (item->dirty) { item->dbar->ops->update(item->dbar, item->it, NULL); item->dirty = EINA_FALSE; } dbar = _get_bar_object(item->dbar); if (bar->cur != item) return; elm_object_part_content_unset(bar->ly, PART_DYNAMICBAR); EINA_LIST_FOREACH(bar->list, l, _item) { if (_item == item) { _item->dbar->ops->show(_item->dbar); continue; } _dbar = _get_bar_object(_item->dbar); _item->dbar->ops->hide(_item->dbar); evas_object_stack_below(_dbar, bar->ly); } elm_object_part_content_set(bar->ly, PART_DYNAMICBAR, dbar); elm_object_signal_emit(dbar, SIG_SHOW, SRC_PROG); } static void _updated(struct engine_bar_item *it, void *data) { struct _hbar_item *item; if (!it || !data) { _ERR("invalid argument"); return; } item = data; item->dirty = EINA_TRUE; item->bar->state = HBAR_STATE_HBAR; _update_child_bar(item->bar, item); if (item->bar->cur == item) elm_object_focus_set(item->eo, EINA_TRUE); } static int _update(struct bar_info *info, void *eng, void *data) { struct _hbar_data *bar; const Eina_List *list; Eina_List *l; struct engine_bar_item *it; struct _hbar_item *item; int cnt, r; if (!info || !info->data) { _ERR("Invalid argument"); return -1; } bar = info->data; EINA_LIST_FREE(bar->list, item) { engine_bar_item_set_update_cb(item->it, NULL, NULL); evas_object_del(item->eo); if (item->dbar) item->dbar->ops->release(item->dbar); free(item); } bar->cur = NULL; bar->list = NULL; cnt = 0; list = engine_get_bar_items(eng); if (!list) return cnt; EINA_LIST_FOREACH((Eina_List *)list, l, it) { r = strcmp(engine_bar_item_get_in(it), "homebar"); if (r != 0) continue; item = _pack_item(bar, it); if (!item) continue; bar->list = eina_list_append(bar->list, item); engine_bar_item_set_update_cb(item->it, _updated, item); cnt++; } r = bar->ubar->ops->update(bar->ubar, eng, NULL); if (r < 0) return -1; return cnt; } static void _show(struct bar_info *info) { struct _hbar_data *bar; struct _hbar_item *item; Eina_List *l; if (!info || !info->data) { _ERR("Invalid argument"); return; } bar = info->data; EINA_LIST_FOREACH(bar->list, l, item) elm_object_focus_allow_set(item->eo, EINA_TRUE); item = bar->cur; if (!item) { item = eina_list_data_get(bar->list); bar->cur = item; } bar->state = HBAR_STATE_HBAR; elm_object_focus_set(item->eo, EINA_TRUE); } static void _hide(struct bar_info *info) { struct _hbar_data *bar; struct _hbar_item *item; Eina_List *l; if (!info || !info->data) { _ERR("Invalid argument"); return; } bar = info->data; item = bar->cur; if (item) elm_object_focus_set(item->eo, EINA_FALSE); EINA_LIST_FOREACH(bar->list, l, item) { elm_object_signal_emit(item->eo, SIG_HIDE, SRC_PROG); elm_object_focus_allow_set(item->eo, EINA_FALSE); } bar->state = HBAR_STATE_HIDE; } static void _release(struct bar_info *info) { struct _hbar_data *bar; struct _hbar_item *item; if (!info) { _ERR("Invalid argument"); return; } bar = info->data; _hide(info); if (bar) { EINA_LIST_FREE(bar->list, item) { engine_bar_item_set_update_cb(item->it, NULL, NULL); evas_object_del(item->eo); if (item->dbar) item->dbar->ops->release(item->dbar); free(item); } if (bar->ubar) bar->ubar->ops->release(bar->ubar); evas_object_del(bar->scr); free(bar); bar = NULL; } free(info); info = NULL; } static struct bar_ops hbar_ops = { .add_bar = _add_bar, .update = _update, .show = _show, .hide = _hide, .is_move = _is_move, .move = _move, .key_down = _key_down, .key_up = _key_up, .release = _release, }; int init_home_bar(struct bar_info *info) { struct _hbar_data *bar; if (!info) return -1; bar = calloc(1, sizeof(*bar)); if (!bar) { _ERR("calloc failed"); return -1; } info->data = bar; info->ops = &hbar_ops; bar->state = HBAR_STATE_HBAR; return 0; }