/* * 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 "bar.h" #include "engine.h" #include "defs.h" #include "dbg.h" enum _hscr_state { HOMESCREEN_STATE_HIDE, HOMESCREEN_STATE_HBAR, HOMESCREEN_STATE_CBAR }; struct homescreen { Evas_Object *base; Evas_Object *win; struct engine *eng; enum _hscr_state state; Eina_Bool focus_lock; struct bar_info *hbar; struct bar_info *cbar; }; static void _outside_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) { elm_win_lower(data); } static Evas_Object *_base_init(Evas_Object *win) { Evas_Object *base; if (!win) return NULL; base = elm_layout_add(win); if (!base) { _ERR("layout add failed"); return NULL; } elm_layout_file_set(base, EDJEFILE, GRP_MAIN); evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(win, base); elm_object_signal_callback_add(base, SIG_OUTSIDE_CLICKED, SRC_EDJE, _outside_clicked, win); evas_object_show(base); return base; } static int _add_hbar(struct homescreen *hscr) { struct bar_info *hbar; int r; if (!hscr) { _ERR("Invalid argument"); return -1; } if (!hscr->base) { _ERR("there is no base"); return -1; } hbar = calloc(1, sizeof(*hbar)); if (!hbar) { _ERR("calloc failed"); return -1; } r = init_home_bar(hbar); if (r < 0) { free(hbar); return -1; } hscr->hbar = hbar; hbar->ops->add_bar(hbar, hscr->base); hbar->ops->update(hbar, hscr->eng, NULL); return 0; } static Eina_Bool _show_bar(struct homescreen *hscr) { if (!hscr) { _ERR("Invalid argument"); return EINA_FALSE; } if (hscr->state != HOMESCREEN_STATE_HIDE) return EINA_FALSE; hscr->focus_lock = EINA_TRUE; elm_object_signal_emit(hscr->base, SIG_SHOW_HOMEBAR, SRC_PROG); if (hscr->hbar) hscr->state = HOMESCREEN_STATE_HBAR; else if (hscr->cbar) hscr->state = HOMESCREEN_STATE_CBAR; return EINA_TRUE; } static Eina_Bool _hide_bar(struct homescreen *hscr) { if (!hscr) { _ERR("Invalid argument"); return EINA_FALSE; } switch (hscr->state) { case HOMESCREEN_STATE_HBAR: case HOMESCREEN_STATE_CBAR: hscr->focus_lock = EINA_TRUE; elm_object_signal_emit(hscr->base, SIG_HIDE_HOMEBAR, SRC_PROG); hscr->state = HOMESCREEN_STATE_HIDE; return EINA_TRUE; default: break; } return EINA_FALSE; } static int _add_cbar(struct homescreen *hscr) { struct bar_info *cbar; int r; if (!hscr) { _ERR("Invalid argument"); return -1; } if (!hscr->base) { _ERR("there is no base"); return -1; } cbar = calloc(1, sizeof(*cbar)); if (!cbar) return -1; r = init_custom_bar(cbar); if (r < 0) { free(cbar); return -1; } hscr->cbar = cbar; r = cbar->ops->add_bar(cbar, hscr->base); if (r < 0) { free(cbar); return -1; } cbar->ops->update(cbar, hscr->eng, NULL); return 0; } static Eina_Bool _move_hbar(struct homescreen *hscr) { int r; if (!hscr) { _ERR("Invalid argument"); return EINA_FALSE; } if (hscr->cbar) { hscr->cbar->ops->release(hscr->cbar); hscr->cbar = NULL; } r = _add_hbar(hscr); if (r < 0) { _ERR("hbar add failed"); return EINA_FALSE; } elm_object_signal_emit(hscr->base, SIG_HIDE_HOMEBAR, SRC_PROG); elm_object_signal_emit(hscr->base, SIG_SHOW_HOMEBAR, SRC_PROG); hscr->state = HOMESCREEN_STATE_HBAR; return EINA_TRUE; } static Eina_Bool _move_cbar(struct homescreen *hscr) { int r; if (!hscr) { _ERR("Invalid argument"); return EINA_FALSE; } if (hscr->hbar) { hscr->hbar->ops->release(hscr->hbar); hscr->hbar = NULL; } r = _add_cbar(hscr); if (r < 0) { _ERR("cbar add failed"); return EINA_FALSE; } elm_object_signal_emit(hscr->base, SIG_HIDE_HOMEBAR, SRC_PROG); elm_object_signal_emit(hscr->base, SIG_SHOW_HOMEBAR, SRC_PROG); hscr->state = HOMESCREEN_STATE_CBAR; return EINA_TRUE; } static Eina_Bool _bar_event(struct homescreen *hscr, enum bar_event ev) { Eina_Bool r; switch (ev) { case BAR_EVENT_MOVE: if (hscr->state == HOMESCREEN_STATE_HBAR) r = _move_cbar(hscr); else if (hscr->state == HOMESCREEN_STATE_CBAR) r = _move_hbar(hscr); else r = ECORE_CALLBACK_PASS_ON; break; case BAR_EVENT_BACK: r = _hide_bar(hscr); break; case BAR_EVENT_DONE: r = ECORE_CALLBACK_CANCEL; break; case BAR_EVENT_PASS: case BAR_EVENT_ERROR: default: r = ECORE_CALLBACK_PASS_ON; break; } return r; } static Eina_Bool _key_up(void *data, int type, void *ei) { struct homescreen *hscr; Eina_Bool r; enum bar_event ev; if (!data || !ei) return ECORE_CALLBACK_PASS_ON; hscr = data; switch (hscr->state) { case HOMESCREEN_STATE_HBAR: if (!hscr->hbar) return ECORE_CALLBACK_CANCEL; ev = hscr->hbar->ops->key_up(hscr->hbar, ei); break; case HOMESCREEN_STATE_CBAR: if (!hscr->cbar) return ECORE_CALLBACK_CANCEL; ev = hscr->cbar->ops->key_up(hscr->cbar, ei); break; default: return ECORE_CALLBACK_PASS_ON; } r = _bar_event(hscr, ev); return r; } static Eina_Bool _key_down(void *data, int type, void *ei) { struct homescreen *hscr; Eina_Bool r; enum bar_event ev; if (!data || !ei) return ECORE_CALLBACK_PASS_ON; hscr = data; switch (hscr->state) { case HOMESCREEN_STATE_HBAR: if (!hscr->hbar) return ECORE_CALLBACK_CANCEL; ev = hscr->hbar->ops->key_down(hscr->hbar, ei); break; case HOMESCREEN_STATE_CBAR: if (!hscr->cbar) return ECORE_CALLBACK_CANCEL; ev = hscr->cbar->ops->key_down(hscr->cbar, ei); break; default: return ECORE_CALLBACK_PASS_ON; } r = _bar_event(hscr, ev); return r; } static void _hbar_show_done(void *data, Evas_Object *eo, const char *emission, const char *source) { struct homescreen *hscr; if (!data) return; hscr = data; switch (hscr->state) { case HOMESCREEN_STATE_HBAR: if (hscr->hbar) hscr->hbar->ops->show(hscr->hbar); break; case HOMESCREEN_STATE_CBAR: if (hscr->cbar) hscr->cbar->ops->show(hscr->cbar); break; default: break; } } static void _hbar_hide_done(void *data, Evas_Object *eo, const char *emission, const char *source) { struct homescreen *hscr; if (!data) return; hscr = data; if (hscr->hbar) hscr->hbar->ops->hide(hscr->hbar); else if (hscr->cbar) hscr->cbar->ops->hide(hscr->cbar); elm_win_lower(hscr->win); } struct homescreen *homescreen_init(struct engine *eng) { struct homescreen *hscr; if (!eng) { _ERR("Invalid argument"); return NULL; } hscr = calloc(1, sizeof(*hscr)); if (!hscr) { _ERR("calloc failed"); return NULL; } ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_down, hscr); ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_up, hscr); hscr->eng = eng; return hscr; } static void _change_state_clicked(void *data, Evas_Object *obj, const char *emission, const char *source) { struct homescreen *hscr; if (!data) return; hscr = data; switch (hscr->state) { case HOMESCREEN_STATE_HBAR: _move_cbar(hscr); break; case HOMESCREEN_STATE_CBAR: _move_hbar(hscr); break; default: break; } } int homescreen_load(struct homescreen *hscr, Evas_Object *win) { Evas_Object *base; int r; if (!hscr || !win) { _ERR("invalid argument"); return -1; } base = _base_init(win); if (!base) return -1; hscr->win = win; hscr->base = base; r = _add_hbar(hscr); if (r != 0) { evas_object_del(hscr->base); return -1; } hscr->state = HOMESCREEN_STATE_HIDE; elm_object_signal_callback_add(hscr->base, SIG_SHOW_HOMEBAR_DONE, SRC_PROG, _hbar_show_done, hscr); elm_object_signal_callback_add(hscr->base, SIG_HIDE_HOMEBAR_DONE, SRC_PROG, _hbar_hide_done, hscr); elm_object_signal_callback_add(hscr->base, SIG_ARROW_CLICKED, SRC_EDJE, _change_state_clicked, hscr); return 0; } void homescreen_fini(struct homescreen *hscr) { if (!hscr) { _ERR("Invalid argument"); return; } if (hscr->hbar) hscr->hbar->ops->release(hscr->hbar); if (hscr->cbar) hscr->cbar->ops->release(hscr->cbar); evas_object_del(hscr->base); free(hscr); } void homescreen_show(struct homescreen *hscr) { if (!hscr) { _ERR("Invalid argument"); return; } _show_bar(hscr); } void homescreen_hide(struct homescreen *hscr) { if (!hscr) { _ERR("Invalid argument"); return; } }