From 755bd961d30452544ea821778aced5b4ba5e697b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= <jean.andre.santoni@gmail.com>
Date: Tue, 20 Oct 2015 19:11:43 +0700
Subject: [PATCH] (XMB) Settings tab

---
 menu/cbs/menu_cbs_left.c  |  2 +-
 menu/cbs/menu_cbs_right.c |  2 +-
 menu/drivers/xmb.c        | 77 +++++++++++++++++++++++++++------------
 menu/intl/menu_hash_us.c  |  2 +
 menu/menu.h               |  1 +
 menu/menu_displaylist.c   |  4 +-
 menu/menu_hash.h          |  1 +
 7 files changed, 62 insertions(+), 27 deletions(-)

diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c
index 27822b21e5..04dcaa88ec 100644
--- a/menu/cbs/menu_cbs_left.c
+++ b/menu/cbs/menu_cbs_left.c
@@ -339,7 +339,7 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs,
 
       if ((parent_group_hash == MENU_VALUE_MAIN_MENU) && (menu_setting_get_type(cbs->setting) == ST_GROUP))
       {
-         BIND_ACTION_LEFT(cbs, action_left_scroll);
+         BIND_ACTION_LEFT(cbs, action_left_mainmenu);
          return 0;
       }
    }
diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c
index 7edc57831f..d795592b5a 100644
--- a/menu/cbs/menu_cbs_right.c
+++ b/menu/cbs/menu_cbs_right.c
@@ -164,7 +164,7 @@ static int action_right_mainmenu(unsigned type, const char *label,
    if (list_size == 1)
    {
       menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection);
-      if (menu_driver_list_get_selection() != (menu_driver_list_get_size(MENU_LIST_HORIZONTAL)))
+      if (menu_driver_list_get_selection() != (menu_driver_list_get_size(MENU_LIST_HORIZONTAL) + 1))
          push_list = 1;
    }
    else
diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c
index ead05edeae..d425b7d9b4 100644
--- a/menu/drivers/xmb.c
+++ b/menu/drivers/xmb.c
@@ -63,7 +63,8 @@ typedef struct
 
 enum
 {
-   XMB_TEXTURE_SETTINGS = 0,
+   XMB_TEXTURE_MAIN_MENU = 0,
+   XMB_TEXTURE_SETTINGS,
    XMB_TEXTURE_SETTING,
    XMB_TEXTURE_SUBSETTING,
    XMB_TEXTURE_ARROW,
@@ -221,7 +222,8 @@ typedef struct xmb_handle
       } passive;
    } item;
 
-   xmb_node_t settings_node;
+   xmb_node_t main_menu_node;
+   xmb_node_t settings_tab_node;
    bool prevent_populate;
 
    gfx_font_raster_block_t raster_block;
@@ -857,12 +859,14 @@ static void xmb_set_title(xmb_handle_t *xmb)
 {
    if (xmb->categories.selection_ptr == 0)
       menu_entries_get_title(xmb->title_name, sizeof(xmb->title_name));
+   else if (xmb->categories.selection_ptr == 1)
+      menu_entries_get_title(xmb->title_name, sizeof(xmb->title_name));
    else
    {
       const char *path = NULL;
       menu_entries_get_at_offset(
             xmb->horizontal_list,
-            xmb->categories.selection_ptr - 1,
+            xmb->categories.selection_ptr - 2,
             &path, NULL, NULL, NULL, NULL);
 
       if (!path)
@@ -877,16 +881,19 @@ static void xmb_set_title(xmb_handle_t *xmb)
 static void xmb_list_switch_horizontal_list(xmb_handle_t *xmb, menu_handle_t *menu)
 {
    unsigned j;
-   size_t list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL);
+   size_t list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL) + 1;
 
    for (j = 0; j <= list_size; j++)
    {
       float ia                    = xmb->categories.passive.alpha;
       float iz                    = xmb->categories.passive.zoom;
-      xmb_node_t *node            = &xmb->settings_node;
+      xmb_node_t *node            = &xmb->main_menu_node;
 
-      if (j > 0)
-         node = xmb_get_userdata_from_horizontal_list(xmb, j - 1);
+      if (j == 1)
+         node = &xmb->settings_tab_node;
+
+      if (j > 1)
+         node = xmb_get_userdata_from_horizontal_list(xmb, j - 2);
 
       if (!node)
          continue;
@@ -950,10 +957,13 @@ static void xmb_list_open_horizontal_list(xmb_handle_t *xmb, menu_handle_t *menu
    for (j = 0; j <= list_size; j++)
    {
       float ia          = 0;
-      xmb_node_t *node  = &xmb->settings_node;
+      xmb_node_t *node  = &xmb->main_menu_node;
 
-      if (j > 0)
-         node = xmb_get_userdata_from_horizontal_list(xmb, j - 1);
+      if (j == 1)
+         node = &xmb->settings_tab_node;
+
+      if (j > 1)
+         node = xmb_get_userdata_from_horizontal_list(xmb, j - 2);
 
       if (!node)
          continue;
@@ -1169,8 +1179,8 @@ static void xmb_draw_items(xmb_handle_t *xmb, gl_t *gl,
    if (!list || !list->size || !menu)
       return;
 
-   if (cat_selection_ptr)
-      core_node = xmb_get_userdata_from_horizontal_list(xmb, cat_selection_ptr - 1);
+   if (cat_selection_ptr > 1)
+      core_node = xmb_get_userdata_from_horizontal_list(xmb, cat_selection_ptr - 2);
 
    end = file_list_get_size(list);
 
@@ -1457,14 +1467,17 @@ static void xmb_frame_horizontal_list(xmb_handle_t *xmb,
       GRfloat *color)
 {
    unsigned i;
-   size_t list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL);
+   size_t list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL) + 1;
 
    for (i = 0; i <= list_size; i++)
    {
-      xmb_node_t *node = &xmb->settings_node;
+      xmb_node_t *node = &xmb->main_menu_node;
 
-      if (i > 0)
-         node = xmb_get_userdata_from_horizontal_list(xmb, i - 1);
+      if (i == 1)
+         node = &xmb->settings_tab_node;
+
+      if (i > 1)
+         node = xmb_get_userdata_from_horizontal_list(xmb, i - 2);
 
       if (!node)
          continue;
@@ -1967,14 +1980,17 @@ static bool xmb_load_image(void *data, menu_image_type_t type)
 static void xmb_toggle_horizontal_list(xmb_handle_t *xmb, menu_handle_t *menu)
 {
    unsigned i;
-   size_t list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL);
+   size_t list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL) + 1;
 
    for (i = 0; i <= list_size; i++)
    {
-      xmb_node_t *node = &xmb->settings_node;
+      xmb_node_t *node = &xmb->main_menu_node;
 
-      if (i > 0)
-         node = xmb_get_userdata_from_horizontal_list(xmb, i - 1);
+      if (i == 1)
+         node = &xmb->settings_tab_node;
+
+      if (i > 1)
+         node = xmb_get_userdata_from_horizontal_list(xmb, i - 2);
 
       if (!node)
          continue;
@@ -2064,6 +2080,9 @@ static void xmb_context_reset_textures(xmb_handle_t *xmb, const char *iconpath)
 
       switch(i)
       {
+         case XMB_TEXTURE_MAIN_MENU:
+            fill_pathname_join(path, iconpath, "main-menu.png", sizeof(path));
+            break;
          case XMB_TEXTURE_SETTINGS:
             fill_pathname_join(path, iconpath, "settings.png",   sizeof(path));
             break;
@@ -2167,9 +2186,13 @@ static void xmb_context_reset_textures(xmb_handle_t *xmb, const char *iconpath)
       texture_image_free(&ti);
    }
 
-   xmb->settings_node.icon  = xmb->textures.list[XMB_TEXTURE_SETTINGS].id;
-   xmb->settings_node.alpha = xmb->categories.active.alpha;
-   xmb->settings_node.zoom  = xmb->categories.active.zoom;
+   xmb->main_menu_node.icon  = xmb->textures.list[XMB_TEXTURE_MAIN_MENU].id;
+   xmb->main_menu_node.alpha = xmb->categories.active.alpha;
+   xmb->main_menu_node.zoom  = xmb->categories.active.zoom;
+
+   xmb->settings_tab_node.icon  = xmb->textures.list[XMB_TEXTURE_SETTINGS].id;
+   xmb->settings_tab_node.alpha = xmb->categories.active.alpha;
+   xmb->settings_tab_node.zoom  = xmb->categories.active.zoom;
 }
 
 static void xmb_context_reset_background(const char *iconpath)
@@ -2412,7 +2435,7 @@ static void xmb_list_cache(menu_list_type_t type, unsigned action)
                break;
          }
 
-         list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL);
+         list_size = xmb_list_get_size(menu, MENU_LIST_HORIZONTAL) + 1;
          if (xmb->categories.selection_ptr > list_size)
          {
             xmb->categories.selection_ptr = list_size;
@@ -2433,6 +2456,12 @@ static void xmb_list_cache(menu_list_type_t type, unsigned action)
                menu_stack->list[stack_size - 1].type = 
                   MENU_SETTINGS;
                break;
+            case 1:
+               menu_stack->list[stack_size - 1].label = 
+                  strdup(menu_hash_to_str(MENU_VALUE_SETTINGS_TAB));
+               menu_stack->list[stack_size - 1].type = 
+                  MENU_SETTINGS_TAB;
+               break;
             default:
                menu_stack->list[stack_size - 1].label = 
                   strdup(menu_hash_to_str(MENU_VALUE_HORIZONTAL_MENU));
diff --git a/menu/intl/menu_hash_us.c b/menu/intl/menu_hash_us.c
index 27e7a3bee4..94c5d444e4 100644
--- a/menu/intl/menu_hash_us.c
+++ b/menu/intl/menu_hash_us.c
@@ -758,6 +758,8 @@ const char *menu_hash_to_str_us(uint32_t hash)
          return "Privacy";
       case MENU_VALUE_HORIZONTAL_MENU:
          return "Horizontal Menu";
+      case MENU_VALUE_SETTINGS_TAB:
+         return "Settings tab";
       case MENU_LABEL_VALUE_NO_SETTINGS_FOUND:
          return "No settings found.";
       case MENU_LABEL_VALUE_NO_PERFORMANCE_COUNTERS:
diff --git a/menu/menu.h b/menu/menu.h
index ea55c4dc74..b462de4453 100644
--- a/menu/menu.h
+++ b/menu/menu.h
@@ -98,6 +98,7 @@ typedef enum
    MENU_FILE_MOVIE,
    MENU_FILE_MUSIC,
    MENU_SETTINGS,
+   MENU_SETTINGS_TAB,
    MENU_SETTING_DRIVER,
    MENU_SETTING_ACTION,
    MENU_SETTING_ACTION_RUN,
diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c
index ddc797129a..8095174245 100644
--- a/menu/menu_displaylist.c
+++ b/menu/menu_displaylist.c
@@ -1552,7 +1552,7 @@ static int menu_displaylist_parse_horizontal_list(menu_displaylist_info_t *info)
    settings_t      *settings           = config_get_ptr();
    menu_handle_t        *menu          = menu_driver_get_ptr();
    struct item_file *item              = (struct item_file*)
-      menu_driver_list_get_entry(MENU_LIST_HORIZONTAL, menu_driver_list_get_selection() - 1);
+      menu_driver_list_get_entry(MENU_LIST_HORIZONTAL, menu_driver_list_get_selection() - 2);
 
    if (!item)
       return -1;
@@ -2843,6 +2843,8 @@ int menu_displaylist_push(file_list_t *list, file_list_t *menu_list)
    {
       case MENU_VALUE_MAIN_MENU:
          return menu_displaylist_push_list(&info, DISPLAYLIST_MAIN_MENU);
+      case MENU_VALUE_SETTINGS_TAB:
+         return menu_displaylist_push_list(&info, DISPLAYLIST_SETTINGS_ALL);
       case MENU_VALUE_HORIZONTAL_MENU:
          return menu_displaylist_push_list(&info, DISPLAYLIST_HORIZONTAL);
    }
diff --git a/menu/menu_hash.h b/menu/menu_hash.h
index b0da22625e..e9f6ef635f 100644
--- a/menu/menu_hash.h
+++ b/menu/menu_hash.h
@@ -554,6 +554,7 @@ extern "C" {
 #define MENU_VALUE_CRC                                                         0x0b88671dU
 #define MENU_VALUE_MORE                                                        0x0b877cafU
 #define MENU_VALUE_HORIZONTAL_MENU                                             0x35761704U
+#define MENU_VALUE_SETTINGS_TAB                                                0x6548d16dU
 #define MENU_VALUE_MAIN_MENU                                                   0x1625971fU   
 #define MENU_LABEL_VALUE_SETTINGS                                              0x8aca3ff6U
 #define MENU_VALUE_INPUT_SETTINGS                                              0xddd30846U