summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2022-11-11 01:27:15 +0100
committerChristian Soffke <christian.soffke@gmail.com>2022-11-14 05:47:10 +0100
commitc088a9453df5fd866f2b1fd5347936c1e015d4f5 (patch)
tree1eb44aa529831197433430f0c333eefe7a2e98f5
parente6ab74d4ac5464e579cccd1d1f6356fc41cd0734 (diff)
downloadrockbox-c088a9453df5fd866f2b1fd5347936c1e015d4f5.tar.gz
rockbox-c088a9453df5fd866f2b1fd5347936c1e015d4f5.zip
Database: Restore selection in lower menu levels
The database only remembered what you'd selected when ascending the menu hierarchy again from a lower level. Now it restores a previous selection going in the other direction as well, when you enter a new menu, as long as the selection at the current level hasn't changed. Change-Id: I5068287ff758a7cfebf1428e9b0ffd30e6ef541e
-rw-r--r--apps/tagtree.c71
-rw-r--r--apps/tagtree.h4
-rw-r--r--apps/tree.c4
3 files changed, 59 insertions, 20 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 11be1425d5..cad12e2a79 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -191,6 +191,7 @@ static int current_entry_count;
191 191
192static struct tree_context *tc; 192static struct tree_context *tc;
193 193
194static int max_history_level; /* depth of menu levels with applicable history */
194static int selected_item_history[MAX_DIR_LEVELS]; 195static int selected_item_history[MAX_DIR_LEVELS];
195static int table_history[MAX_DIR_LEVELS]; 196static int table_history[MAX_DIR_LEVELS];
196static int extra_history[MAX_DIR_LEVELS]; 197static int extra_history[MAX_DIR_LEVELS];
@@ -1248,6 +1249,7 @@ static void tagtree_unload(struct tree_context *c)
1248 1249
1249void tagtree_init(void) 1250void tagtree_init(void)
1250{ 1251{
1252 max_history_level = 0;
1251 format_count = 0; 1253 format_count = 0;
1252 menu_count = 0; 1254 menu_count = 0;
1253 menu = NULL; 1255 menu = NULL;
@@ -1818,7 +1820,16 @@ int tagtree_load(struct tree_context* c)
1818 return count; 1820 return count;
1819} 1821}
1820 1822
1821int tagtree_enter(struct tree_context* c) 1823/* Enters menu or table for selected item in the database.
1824 *
1825 * Call this with the is_visible parameter set to false to
1826 * prevent selected_item_history from being updated or applied, in
1827 * case the menus aren't displayed to the user.
1828 * Before calling tagtree_enter again with the parameter set to
1829 * true, make sure that you are back at the previous dirlevel, by
1830 * calling tagtree_exit as needed, with is_visible set to false.
1831 */
1832int tagtree_enter(struct tree_context* c, bool is_visible)
1822{ 1833{
1823 int rc = 0; 1834 int rc = 0;
1824 struct tagentry *dptr; 1835 struct tagentry *dptr;
@@ -1826,14 +1837,17 @@ int tagtree_enter(struct tree_context* c)
1826 int newextra; 1837 int newextra;
1827 int seek; 1838 int seek;
1828 int source; 1839 int source;
1840 bool is_random_item = false;
1841 bool adjust_selection = true;
1829 1842
1830 dptr = tagtree_get_entry(c, c->selected_item); 1843 dptr = tagtree_get_entry(c, c->selected_item);
1831 1844
1832 c->dirfull = false; 1845 c->dirfull = false;
1833 seek = dptr->extraseek; 1846 seek = dptr->extraseek;
1834 if (seek == -1) 1847 if (seek == -1) /* <Random> menu item was selected */
1835 { 1848 {
1836 if(c->filesindir<=2) 1849 is_random_item = true;
1850 if(c->filesindir<=2) /* Menu contains only <All> and <Random> menu items */
1837 return 0; 1851 return 0;
1838 srand(current_tick); 1852 srand(current_tick);
1839 dptr = (tagtree_get_entry(c, 2+(rand() % (c->filesindir-2)))); 1853 dptr = (tagtree_get_entry(c, 2+(rand() % (c->filesindir-2))));
@@ -1844,7 +1858,21 @@ int tagtree_enter(struct tree_context* c)
1844 if (c->dirlevel >= MAX_DIR_LEVELS) 1858 if (c->dirlevel >= MAX_DIR_LEVELS)
1845 return 0; 1859 return 0;
1846 1860
1847 selected_item_history[c->dirlevel]=c->selected_item; 1861 if (is_visible) /* update selection history only for user-selected items */
1862 {
1863 /* We need to discard selected item history for levels
1864 descending from current one if selection has changed */
1865 if (max_history_level < c->dirlevel + 1
1866 || (max_history_level > c->dirlevel
1867 && selected_item_history[c->dirlevel] != c->selected_item)
1868 || is_random_item)
1869 {
1870 max_history_level = c->dirlevel + 1;
1871 selected_item_history[c->dirlevel + 1] = 0;
1872 }
1873
1874 selected_item_history[c->dirlevel]=c->selected_item;
1875 }
1848 table_history[c->dirlevel] = c->currtable; 1876 table_history[c->dirlevel] = c->currtable;
1849 extra_history[c->dirlevel] = c->currextra; 1877 extra_history[c->dirlevel] = c->currextra;
1850 c->dirlevel++; 1878 c->dirlevel++;
@@ -1853,8 +1881,6 @@ int tagtree_enter(struct tree_context* c)
1853 tree_lock_cache(c); 1881 tree_lock_cache(c);
1854 core_pin(tagtree_handle); 1882 core_pin(tagtree_handle);
1855 1883
1856 bool reset_selection = true;
1857
1858 switch (c->currtable) { 1884 switch (c->currtable) {
1859 case ROOT: 1885 case ROOT:
1860 c->currextra = newextra; 1886 c->currextra = newextra;
@@ -1890,6 +1916,10 @@ int tagtree_enter(struct tree_context* c)
1890 if (source == source_constant) 1916 if (source == source_constant)
1891 continue; 1917 continue;
1892 1918
1919 /* discard history for lower levels when doing runtime searches */
1920 if (is_visible)
1921 max_history_level = c->dirlevel - 1;
1922
1893 searchstring=csi->clause[i][j]->str; 1923 searchstring=csi->clause[i][j]->str;
1894 *searchstring = '\0'; 1924 *searchstring = '\0';
1895 1925
@@ -1919,7 +1949,7 @@ int tagtree_enter(struct tree_context* c)
1919 rc = kbd_input(searchstring, SEARCHSTR_SIZE, NULL); 1949 rc = kbd_input(searchstring, SEARCHSTR_SIZE, NULL);
1920 if (rc < 0 || !searchstring[0]) 1950 if (rc < 0 || !searchstring[0])
1921 { 1951 {
1922 tagtree_exit(c); 1952 tagtree_exit(c, is_visible);
1923 tree_unlock_cache(c); 1953 tree_unlock_cache(c);
1924 core_unpin(tagtree_handle); 1954 core_unpin(tagtree_handle);
1925 return 0; 1955 return 0;
@@ -1940,7 +1970,7 @@ int tagtree_enter(struct tree_context* c)
1940 case ALLSUBENTRIES: 1970 case ALLSUBENTRIES:
1941 if (newextra == PLAYTRACK) 1971 if (newextra == PLAYTRACK)
1942 { 1972 {
1943 reset_selection = false; 1973 adjust_selection = false;
1944 1974
1945 if (global_settings.party_mode && audio_status()) { 1975 if (global_settings.party_mode && audio_status()) {
1946 splash(HZ, ID2P(LANG_PARTY_MODE)); 1976 splash(HZ, ID2P(LANG_PARTY_MODE));
@@ -1973,9 +2003,12 @@ int tagtree_enter(struct tree_context* c)
1973 break; 2003 break;
1974 } 2004 }
1975 2005
1976 if (reset_selection) 2006 if (adjust_selection)
1977 { 2007 {
1978 c->selected_item=0; 2008 if (is_visible && c->dirlevel <= max_history_level)
2009 c->selected_item = selected_item_history[c->dirlevel];
2010 else
2011 c->selected_item = 0;
1979 } 2012 }
1980 2013
1981 tree_unlock_cache(c); 2014 tree_unlock_cache(c);
@@ -1984,12 +2017,16 @@ int tagtree_enter(struct tree_context* c)
1984 return rc; 2017 return rc;
1985} 2018}
1986 2019
1987void tagtree_exit(struct tree_context* c) 2020/* Exits current database menu or table */
2021void tagtree_exit(struct tree_context* c, bool is_visible)
1988{ 2022{
2023 if (is_visible) /* update selection history only for user-selected items */
2024 selected_item_history[c->dirlevel] = c->selected_item;
1989 c->dirfull = false; 2025 c->dirfull = false;
1990 if (c->dirlevel > 0) 2026 if (c->dirlevel > 0)
1991 c->dirlevel--; 2027 c->dirlevel--;
1992 c->selected_item=selected_item_history[c->dirlevel]; 2028 if (is_visible)
2029 c->selected_item=selected_item_history[c->dirlevel];
1993 c->currtable = table_history[c->dirlevel]; 2030 c->currtable = table_history[c->dirlevel];
1994 c->currextra = extra_history[c->dirlevel]; 2031 c->currextra = extra_history[c->dirlevel];
1995} 2032}
@@ -2083,6 +2120,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue)
2083{ 2120{
2084 char buf[MAX_PATH]; 2121 char buf[MAX_PATH];
2085 int dirlevel = tc->dirlevel; 2122 int dirlevel = tc->dirlevel;
2123 int selected_item = tc->selected_item;
2086 int newtable; 2124 int newtable;
2087 2125
2088 show_search_progress( 2126 show_search_progress(
@@ -2112,7 +2150,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue)
2112 2150
2113 if (newtable == NAVIBROWSE) 2151 if (newtable == NAVIBROWSE)
2114 { 2152 {
2115 tagtree_enter(tc); 2153 tagtree_enter(tc, false);
2116 tagtree_load(tc); 2154 tagtree_load(tc);
2117 newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; 2155 newtable = tagtree_get_entry(tc, tc->selected_item)->newtable;
2118 } 2156 }
@@ -2125,7 +2163,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue)
2125 /* Now the current table should be allsubentries. */ 2163 /* Now the current table should be allsubentries. */
2126 if (newtable != PLAYTRACK) 2164 if (newtable != PLAYTRACK)
2127 { 2165 {
2128 tagtree_enter(tc); 2166 tagtree_enter(tc, false);
2129 tagtree_load(tc); 2167 tagtree_load(tc);
2130 newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; 2168 newtable = tagtree_get_entry(tc, tc->selected_item)->newtable;
2131 2169
@@ -2134,7 +2172,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue)
2134 { 2172 {
2135 logf("newtable: %d !!", newtable); 2173 logf("newtable: %d !!", newtable);
2136 while (tc->dirlevel > dirlevel) 2174 while (tc->dirlevel > dirlevel)
2137 tagtree_exit(tc); 2175 tagtree_exit(tc, false);
2138 tagtree_load(tc); 2176 tagtree_load(tc);
2139 return false; 2177 return false;
2140 } 2178 }
@@ -2151,7 +2189,8 @@ bool tagtree_insert_selection_playlist(int position, bool queue)
2151 2189
2152 /* Finally return the dirlevel to its original value. */ 2190 /* Finally return the dirlevel to its original value. */
2153 while (tc->dirlevel > dirlevel) 2191 while (tc->dirlevel > dirlevel)
2154 tagtree_exit(tc); 2192 tagtree_exit(tc, false);
2193 tc->selected_item = selected_item;
2155 tagtree_load(tc); 2194 tagtree_load(tc);
2156 2195
2157 return true; 2196 return true;
diff --git a/apps/tagtree.h b/apps/tagtree.h
index 427a602df6..5c938b1541 100644
--- a/apps/tagtree.h
+++ b/apps/tagtree.h
@@ -34,8 +34,8 @@
34int tagtree_export(void); 34int tagtree_export(void);
35int tagtree_import(void); 35int tagtree_import(void);
36void tagtree_init(void) INIT_ATTR; 36void tagtree_init(void) INIT_ATTR;
37int tagtree_enter(struct tree_context* c); 37int tagtree_enter(struct tree_context* c, bool is_visible);
38void tagtree_exit(struct tree_context* c); 38void tagtree_exit(struct tree_context* c, bool is_visible);
39int tagtree_load(struct tree_context* c); 39int tagtree_load(struct tree_context* c);
40char* tagtree_get_entry_name(struct tree_context *c, int id, 40char* tagtree_get_entry_name(struct tree_context *c, int id,
41 char* buf, size_t bufsize); 41 char* buf, size_t bufsize);
diff --git a/apps/tree.c b/apps/tree.c
index 70f2704fae..1939c7ee05 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -683,7 +683,7 @@ static int dirbrowse(void)
683 } 683 }
684 } 684 }
685#ifdef HAVE_TAGCACHE 685#ifdef HAVE_TAGCACHE
686 switch (id3db?tagtree_enter(&tc):ft_enter(&tc)) 686 switch (id3db ? tagtree_enter(&tc, true) : ft_enter(&tc))
687#else 687#else
688 switch (ft_enter(&tc)) 688 switch (ft_enter(&tc))
689#endif 689#endif
@@ -723,7 +723,7 @@ static int dirbrowse(void)
723 723
724#ifdef HAVE_TAGCACHE 724#ifdef HAVE_TAGCACHE
725 if (id3db) 725 if (id3db)
726 tagtree_exit(&tc); 726 tagtree_exit(&tc, true);
727 else 727 else
728#endif 728#endif
729 if (ft_exit(&tc) == 3) 729 if (ft_exit(&tc) == 3)