base: add focus handling between menu button and thumbnail area 78/43978/6
authorJehun Lim <jehun.lim@samsung.com>
Wed, 15 Jul 2015 13:04:16 +0000 (22:04 +0900)
committerJehun Lim <jehun.lim@samsung.com>
Thu, 16 Jul 2015 12:32:44 +0000 (21:32 +0900)
Change-Id: Ib9fce52084db6b0b5ea730b6dd0bf20546f72dfc
Signed-off-by: Jehun Lim <jehun.lim@samsung.com>
include/util/listmgr.h
src/layout/gallery.c
src/layout/movie.c
src/util/listmgr.c
src/view/base.c

index 7272023..3567dd0 100644 (file)
@@ -33,6 +33,8 @@ struct grid_ops {
 };
 
 struct listmgr_data {
+       Evas_Object *menu_btn;
+
        int grid_item_x;
        int grid_item_y;
        int grid_num_item;
index ed45631..8d396af 100644 (file)
@@ -42,6 +42,7 @@
 struct _priv {
        Evas_Object *base;
        Evas_Object *layout;
+       Evas_Object *menu_btn;
 
        layoutmgr *lmgr;
 
@@ -134,6 +135,8 @@ static struct listmgr_data *_create_listmgr_data(struct _priv *priv)
        if (!data)
                goto err;
 
+       data->menu_btn = priv->menu_btn;
+
        data->grid_item_x = GRID_ITEM_X;
        data->grid_item_y = GRID_ITEM_Y;
        data->grid_num_item = GRID_NUM_ITEM;
@@ -189,12 +192,19 @@ static bool _create(layoutmgr *lmgr, void *data)
                return false;
        }
 
+       if (!data) {
+               _ERR("invalid argument");
+               return false;
+       }
+
        priv = calloc(1, sizeof(*priv));
        if (!priv) {
                _ERR("failed to allocate priv");
                return false;
        }
 
+       priv->menu_btn = (Evas_Object *)data;
+
        base = layoutmgr_get_base(lmgr);
        if (!base) {
                _ERR("failed to get base object");
index 1944c65..d6d3e8d 100644 (file)
@@ -44,6 +44,7 @@ struct _priv {
        Evas_Object *base;
        Evas_Object *layout;
        Evas_Object *box;
+       Evas_Object *menu_btn;
 
        layoutmgr *lmgr;
 
@@ -283,6 +284,8 @@ static struct listmgr_data *_create_listmgr_data(struct _priv *priv)
        if (!data)
                goto err;
 
+       data->menu_btn = priv->menu_btn;
+
        data->grid_item_x = GRID_ITEM_X;
        data->grid_item_y = GRID_ITEM_Y;
        data->grid_num_item = GRID_NUM_ITEM;
@@ -349,12 +352,19 @@ static bool _create(layoutmgr *lmgr, void *data)
                return false;
        }
 
+       if (!data) {
+               _ERR("invalid argument");
+               return false;
+       }
+
        priv = calloc(1, sizeof(*priv));
        if (!priv) {
                _ERR("failed to allocate priv");
                return false;
        }
 
+       priv->menu_btn = (Evas_Object *)data;
+
        base = layoutmgr_get_base(lmgr);
        if (!base) {
                _ERR("failed to get base object");
index efc3e28..63fad7f 100644 (file)
 #define SCROLLER_STEP_SIZE(x) ((x) + 10)
 
 enum _object_type {
-       LISTMGR_GRID = 0,
+       LISTMGR_SCROLLER = 0,
+       LISTMGR_INDEX,
+       LISTMGR_GRID
 };
 
 struct listmgr {
        Evas_Object *base;
+       Evas_Object *scr;
        Evas_Object *box;
        Evas_Object *play_info;
+       Evas_Object *focused;
 
        struct gridmgr *gmgr;
        struct listmgr_data *data;
 
        Eina_Bool show_play_info;
+       Eina_Bool scr_focus;
 };
 
-void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj,
+static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj,
+                       Evas_Event_Key_Down *ev)
+{
+       if (!obj || !ev)
+               return;
+
+       switch (id) {
+       case LISTMGR_INDEX:
+               if (!strcmp(ev->keyname, KEY_BACK) ||
+                       !strcmp(ev->keyname, KEY_BACK_REMOTE))
+                       elm_object_focus_next(obj, ELM_FOCUS_UP);
+               break;
+       default:
+               break;
+       }
+}
+
+static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj,
                        Evas_Event_Mouse_Move *ev)
 {
        Elm_Object_Item *it;
+       struct listmgr *lmgr;
 
-       if (!obj || !ev)
+       if (!data || !obj || !ev)
                return;
 
+       lmgr = data;
+
        switch (id) {
+       case LISTMGR_INDEX:
+               if (!elm_object_focus_get(obj)) {
+                       lmgr->scr_focus = EINA_FALSE;
+                       elm_object_focus_set(obj, EINA_TRUE);
+               }
+
+               break;
        case LISTMGR_GRID:
                it = elm_gengrid_at_xy_item_get(obj, ev->cur.canvas.x,
                                        ev->cur.canvas.y, NULL, NULL);
@@ -59,8 +91,10 @@ void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj,
                if (!it)
                        return;
 
-               if (!elm_object_item_focus_get(it))
+               if (!elm_object_item_focus_get(it)) {
+                       lmgr->scr_focus = EINA_FALSE;
                        elm_object_item_focus_set(it, EINA_TRUE);
+               }
 
                break;
        default:
@@ -68,7 +102,7 @@ void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj,
        }
 }
 
-void _grid_selected_cb(void *data, Elm_Object_Item *it,
+static void _grid_selected_cb(void *data, Elm_Object_Item *it,
                        const char *emission, const char *source)
 {
        struct listmgr *lmgr;
@@ -86,7 +120,7 @@ void _grid_selected_cb(void *data, Elm_Object_Item *it,
        elm_gengrid_item_selected_set(it, EINA_FALSE);
 }
 
-void _grid_realized_cb(int id, void *data, Evas_Object *obj,
+static void _grid_realized_cb(int id, void *data, Evas_Object *obj,
                        Elm_Object_Item *it)
 {
        if (!data || !it)
@@ -96,7 +130,7 @@ void _grid_realized_cb(int id, void *data, Evas_Object *obj,
                                SIG_SOURCE_EDC, _grid_selected_cb, data);
 }
 
-void _grid_unrealized_cb(int id, void *data, Evas_Object *obj,
+static void _grid_unrealized_cb(int id, void *data, Evas_Object *obj,
                        Elm_Object_Item *it)
 {
        if (!it)
@@ -106,12 +140,66 @@ void _grid_unrealized_cb(int id, void *data, Evas_Object *obj,
                                SIG_SOURCE_EDC, _grid_selected_cb);
 }
 
+static void _focused_cb(int id, void *data, Evas_Object *obj,
+                       Elm_Object_Item *it)
+{
+       Evas_Object *btn;
+       struct listmgr *lmgr;
+
+       if (!data || !obj)
+               return;
+
+       lmgr = data;
+
+       switch (id) {
+       case LISTMGR_SCROLLER:
+               if (!lmgr->scr_focus)
+                       break;
+
+               btn = elm_object_part_content_get(lmgr->focused,
+                               PART_ITEM_TITLE);
+               if (!btn) {
+                       _ERR("failed to get button object");
+                       return;
+               }
+
+               elm_object_focus_set(btn, EINA_TRUE);
+
+               break;
+       case LISTMGR_INDEX:
+       case LISTMGR_GRID:
+               lmgr->focused =  elm_object_parent_widget_get(obj);
+               lmgr->scr_focus = EINA_TRUE;
+               break;
+       default:
+               break;
+       }
+}
+
 static input_handler _grid_handler = {
        .mouse_move = _mouse_move_cb,
+       .focused = _focused_cb,
        .realized = _grid_realized_cb,
        .unrealized = _grid_unrealized_cb
 };
 
+static input_handler _handler = {
+       .key_down = _key_down_cb,
+       .mouse_move = _mouse_move_cb,
+       .focused = _focused_cb
+};
+
+static Evas_Object *_get_box_first_item(Evas_Object *box)
+{
+       Eina_List *list;
+
+       list = elm_box_children_get(box);
+       if (!list)
+               return NULL;
+
+       return (Evas_Object *)eina_list_nth(list, 0);
+}
+
 static int _get_grid_size(int count, int num_item)
 {
        int size;
@@ -178,6 +266,11 @@ static Evas_Object *_draw_list_item(struct listmgr *lmgr, struct group_info *gi)
        snprintf(buf, sizeof(buf), " %s ", gi->name);
        elm_object_text_set(btn, buf);
 
+       elm_object_focus_next_object_set(btn,
+                               lmgr->data->menu_btn, ELM_FOCUS_UP);
+
+       inputmgr_add_callback(btn, LISTMGR_INDEX, &_handler, lmgr);
+
        grid = util_add_gengrid(ly, data->grid_item_x, data->grid_item_y);
        if (!grid) {
                _ERR("failed to create gengrid object");
@@ -241,7 +334,8 @@ bool listmgr_update_focus_item(struct listmgr *lmgr, int index)
        }
 
        elm_gengrid_item_bring_in(it, ELM_GENGRID_ITEM_SCROLLTO_MIDDLE);
-       elm_object_focus_set(grid, EINA_TRUE);
+
+       lmgr->scr_focus = EINA_FALSE;
        elm_object_item_focus_set(it, EINA_TRUE);
 
        return true;
@@ -249,7 +343,7 @@ bool listmgr_update_focus_item(struct listmgr *lmgr, int index)
 
 bool listmgr_update_content_list(struct listmgr *lmgr, Eina_List *list)
 {
-       Evas_Object *ly;
+       Evas_Object *ly, *btn, *grid;
        Eina_List *l;
        struct group_info *gi;
 
@@ -258,6 +352,7 @@ bool listmgr_update_content_list(struct listmgr *lmgr, Eina_List *list)
                return false;
        }
 
+       ly = NULL;
        EINA_LIST_FOREACH(list, l, gi) {
                ly = _draw_list_item(lmgr, gi);
                if (!ly) {
@@ -275,6 +370,14 @@ bool listmgr_update_content_list(struct listmgr *lmgr, Eina_List *list)
                elm_box_pack_end(lmgr->box, ly);
        }
 
+       btn = elm_object_part_content_get(ly, PART_ITEM_TITLE);
+       elm_object_focus_next_object_set(btn, btn, ELM_FOCUS_RIGHT);
+
+       grid = elm_object_part_content_get(ly, PART_ITEM_CONTENT);
+       elm_object_focus_next_object_set(grid, grid, ELM_FOCUS_RIGHT);
+
+       lmgr->focused = _get_box_first_item(lmgr->box);
+
        return true;
 }
 
@@ -289,6 +392,9 @@ bool listmgr_update_play_info(struct listmgr *lmgr, app_media_info *info)
 
        if (!info) {
                if (lmgr->show_play_info) {
+                       if (lmgr->play_info == lmgr->focused)
+                               lmgr->focused = _get_box_first_item(lmgr->box);
+
                        elm_box_unpack(lmgr->box, lmgr->play_info);
                        evas_object_hide(lmgr->play_info);
                        lmgr->show_play_info = EINA_FALSE;
@@ -330,6 +436,8 @@ bool listmgr_draw_list_area(struct listmgr *lmgr)
        elm_scroller_step_size_set(scr,
                        SCROLLER_STEP_SIZE(lmgr->data->box_padding), 0);
 
+       inputmgr_add_callback(scr, LISTMGR_SCROLLER, &_handler, lmgr);
+
        box = util_add_box(scr);
        if (!box) {
                _ERR("failed to create box object");
@@ -344,6 +452,7 @@ bool listmgr_draw_list_area(struct listmgr *lmgr)
 
        elm_object_part_content_set(lmgr->base, PART_CONTENT, scr);
 
+       lmgr->scr = scr;
        lmgr->box = box;
 
        if (lmgr->data->pops) {
@@ -354,6 +463,9 @@ bool listmgr_draw_list_area(struct listmgr *lmgr)
                }
        }
 
+       elm_object_focus_next_object_set(lmgr->data->menu_btn, scr,
+                               ELM_FOCUS_DOWN);
+
        return true;
 }
 
@@ -384,17 +496,32 @@ struct listmgr *listmgr_create(Evas_Object *base, void *data)
        lmgr->gmgr = gmgr;
        lmgr->data = (struct listmgr_data *)data;
        lmgr->show_play_info = EINA_FALSE;
+       lmgr->scr_focus = EINA_TRUE;
 
        return lmgr;
 }
 
 void listmgr_destroy(struct listmgr *lmgr)
 {
+       Eina_List *item, *l;
+       Evas_Object *ly, *btn, *grid;
+
        if (!lmgr) {
                _ERR("invalid argument");
                return;
        }
 
+       item = elm_box_children_get(lmgr->box);
+       EINA_LIST_FOREACH(item, l, ly) {
+               btn = elm_object_part_content_get(ly, PART_ITEM_TITLE);
+               grid = elm_object_part_content_get(ly, PART_ITEM_CONTENT);
+
+               inputmgr_remove_callback(btn, &_handler);
+               inputmgr_remove_callback(grid, &_grid_handler);
+       }
+
+       inputmgr_remove_callback(lmgr->scr, &_handler);
+
        gridmgr_destroy(lmgr->gmgr);
 
        free(lmgr);
index f2411d7..b726a37 100644 (file)
@@ -43,23 +43,38 @@ struct _priv {
 struct _menu_item {
        const char *name;
        const char *layout_id;
+       layout_class *(*func_get_lclass)(void);
 };
 
 static struct _menu_item g_menu_item[MENU_BTN_SIZE] = {
        {
                "Movie",
-               LAYOUT_MOVIE
+               LAYOUT_MOVIE,
+               layout_movie_get_lclass
        },
        {
                "Gallery",
-               LAYOUT_GALLERY
+               LAYOUT_GALLERY,
+               layout_gallery_get_lclass
        },
        {
                "Music",
-               LAYOUT_MUSIC
+               LAYOUT_MUSIC,
+               layout_music_get_lclass
        }
 };
 
+static void _key_down_cb(int id, void *data, Evas *e, Evas_Object *obj,
+                       Evas_Event_Key_Down *ev)
+{
+       if (!obj || !ev)
+               return;
+
+       if (!strcmp(ev->keyname, KEY_ENTER) ||
+               !strcmp(ev->keyname, KEY_ENTER_REMOTE))
+               elm_object_focus_next(obj, ELM_FOCUS_DOWN);
+}
+
 static void _mouse_move_cb(int id, void *data, Evas *e,
                        Evas_Object *obj, Evas_Event_Mouse_Move *ev)
 {
@@ -102,6 +117,7 @@ static void _focused_cb(int id, void *data, Evas_Object *obj,
 }
 
 static input_handler handler = {
+       .key_down = _key_down_cb,
        .mouse_move = _mouse_move_cb,
        .focused = _focused_cb
 };
@@ -160,8 +176,6 @@ static bool _draw_menu_btn(struct _priv *priv)
 
        elm_object_part_content_set(priv->base, PART_MENU_AREA, box);
 
-       elm_object_focus_set(priv->btn[0], EINA_TRUE);
-
        elm_object_focus_next_object_set(priv->btn[MENU_BTN_SIZE - 1],
                                priv->btn[0], ELM_FOCUS_RIGHT);
        elm_object_focus_next_object_set(priv->btn[0],
@@ -189,6 +203,7 @@ static Evas_Object *_create(Evas_Object *win, void *data)
        struct _priv *priv;
        Evas_Object *base;
        layoutmgr *lmgr;
+       int i;
 
        if (!win) {
                _ERR("failed to get win object");
@@ -210,17 +225,12 @@ static Evas_Object *_create(Evas_Object *win, void *data)
 
        elm_layout_file_set(base, EDJEFILE, GRP_BASE_VIEW);
 
-       evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
+                               EVAS_HINT_EXPAND);
        elm_win_resize_object_add(win, base);
 
-       lmgr = layoutmgr_create(base);
-       layoutmgr_add_layout(lmgr, layout_movie_get_lclass(), NULL);
-       layoutmgr_add_layout(lmgr, layout_gallery_get_lclass(), NULL);
-       layoutmgr_add_layout(lmgr, layout_music_get_lclass(), NULL);
-
        priv->win = win;
        priv->base = base;
-       priv->lmgr = lmgr;
 
        if (!_draw_items(priv)) {
                _ERR("failed to draw items");
@@ -228,8 +238,17 @@ static Evas_Object *_create(Evas_Object *win, void *data)
                return NULL;
        }
 
+       lmgr = layoutmgr_create(base);
+       for (i = 0; i < MENU_BTN_SIZE; i++)
+               layoutmgr_add_layout(lmgr, g_menu_item[i].func_get_lclass(),
+                                       priv->btn[i]);
+
+       priv->lmgr = lmgr;
+
        viewmgr_set_view_data(VIEW_BASE, priv);
 
+       elm_object_focus_set(priv->btn[0], EINA_TRUE);
+
        return base;
 }