summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-08-15 08:14:46 +0000
committerDave Chapman <dave@dchapman.com>2006-08-15 08:14:46 +0000
commit079ad11896d68f16f23880f4de869bbb47617c19 (patch)
tree54e7d33c26da5dfe8d432f2affffbb00273ac8e3
parentedf3bcf15b2e3d2c0e16f25cf565ab3338a1d6c0 (diff)
downloadrockbox-079ad11896d68f16f23880f4de869bbb47617c19.tar.gz
rockbox-079ad11896d68f16f23880f4de869bbb47617c19.zip
Patch #5795 from Jonathan Gordon - change the settings display for enumerations and integers to use the list widget. Patch also adds an optional title to the list widget which is used in the settings.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10576 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/SOURCES1
-rw-r--r--apps/gui/list.c68
-rw-r--r--apps/gui/list.h8
-rw-r--r--apps/settings.c212
-rw-r--r--apps/settings_menu.c7
5 files changed, 197 insertions, 99 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 7580c5e3f6..3548980f28 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -39,7 +39,6 @@ gui/logo.c
39gui/option_select.c 39gui/option_select.c
40gui/quickscreen.c 40gui/quickscreen.c
41gui/scrollbar.c 41gui/scrollbar.c
42gui/select.c
43gui/splash.c 42gui/splash.c
44gui/statusbar.c 43gui/statusbar.c
45gui/textarea.c 44gui/textarea.c
diff --git a/apps/gui/list.c b/apps/gui/list.c
index ebb915e0bc..98b0148c14 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -22,6 +22,7 @@
22#include "font.h" 22#include "font.h"
23#include "button.h" 23#include "button.h"
24#include "sprintf.h" 24#include "sprintf.h"
25#include "string.h"
25#include "settings.h" 26#include "settings.h"
26#include "kernel.h" 27#include "kernel.h"
27 28
@@ -66,6 +67,7 @@ void gui_list_init(struct gui_list * gui_list,
66#endif 67#endif
67 gui_list->scroll_all=scroll_all; 68 gui_list->scroll_all=scroll_all;
68 gui_list->selected_size=selected_size; 69 gui_list->selected_size=selected_size;
70 gui_list->title = NULL;
69} 71}
70 72
71void gui_list_set_display(struct gui_list * gui_list, struct screen * display) 73void gui_list_set_display(struct gui_list * gui_list, struct screen * display)
@@ -117,6 +119,8 @@ void gui_list_put_selection_in_screen(struct gui_list * gui_list,
117#endif 119#endif
118 gui_textarea_update_nblines(gui_list->display); 120 gui_textarea_update_nblines(gui_list->display);
119 int nb_lines=gui_list->display->nb_lines; 121 int nb_lines=gui_list->display->nb_lines;
122 if (gui_list->title)
123 nb_lines--;
120 if(put_from_end) 124 if(put_from_end)
121 { 125 {
122 int list_end = gui_list->selected_item + SCROLL_LIMIT; 126 int list_end = gui_list->selected_item + SCROLL_LIMIT;
@@ -147,13 +151,28 @@ void gui_list_draw(struct gui_list * gui_list)
147 bool draw_icons = (gui_list->callback_get_item_icon != NULL ) ; 151 bool draw_icons = (gui_list->callback_get_item_icon != NULL ) ;
148 bool draw_cursor; 152 bool draw_cursor;
149 int i; 153 int i;
154 int lines;
150 155
151 /* Adjust the position of icon, cursor, text */ 156 /* Adjust the position of icon, cursor, text */
157 if (gui_list->title)
158 {
159 i = 1;
160 lines = display->nb_lines - 1;
161 }
162 else
163 {
164 i = 0;
165 lines = display->nb_lines;
166 }
152#ifdef HAVE_LCD_BITMAP 167#ifdef HAVE_LCD_BITMAP
153 display->setfont(FONT_UI); 168 display->setfont(FONT_UI);
154 gui_textarea_update_nblines(display); 169 gui_textarea_update_nblines(display);
155 bool draw_scrollbar = (global_settings.scrollbar && 170 bool draw_scrollbar;
156 display->nb_lines < gui_list->nb_items); 171
172
173 draw_scrollbar = (global_settings.scrollbar &&
174 lines < gui_list->nb_items);
175
157 draw_cursor = !global_settings.invert_cursor; 176 draw_cursor = !global_settings.invert_cursor;
158 text_pos = 0; /* here it's in pixels */ 177 text_pos = 0; /* here it's in pixels */
159 if(draw_scrollbar) 178 if(draw_scrollbar)
@@ -182,11 +201,12 @@ void gui_list_draw(struct gui_list * gui_list)
182 screen_set_xmargin(display, text_pos); 201 screen_set_xmargin(display, text_pos);
183#endif 202#endif
184 203
185 for(i = 0;i < display->nb_lines;i++) 204
205 while (i < display->nb_lines)
186 { 206 {
187 char entry_buffer[MAX_PATH]; 207 char entry_buffer[MAX_PATH];
188 unsigned char *entry_name; 208 unsigned char *entry_name;
189 int current_item = gui_list->start_item + i; 209 int current_item = gui_list->start_item + (gui_list->title?i-1:i);
190 210
191 /* When there are less items to display than the 211 /* When there are less items to display than the
192 * current available space on the screen, we stop*/ 212 * current available space on the screen, we stop*/
@@ -268,19 +288,31 @@ void gui_list_draw(struct gui_list * gui_list)
268 if(icon) 288 if(icon)
269 screen_put_iconxy(display, icon_pos, i, icon); 289 screen_put_iconxy(display, icon_pos, i, icon);
270 } 290 }
291 i++;
271 } 292 }
272#ifdef HAVE_LCD_BITMAP 293
294#ifdef HAVE_LCD_BITMAP
273 /* Draw the scrollbar if needed*/ 295 /* Draw the scrollbar if needed*/
274 if(draw_scrollbar) 296 if(draw_scrollbar)
275 { 297 {
276 int y_start = gui_textarea_get_ystart(display); 298 int y_start = gui_textarea_get_ystart(display);
299 if (gui_list->title)
300 y_start += display->char_height;
277 int scrollbar_y_end = display->char_height * 301 int scrollbar_y_end = display->char_height *
278 display->nb_lines + y_start; 302 lines + y_start;
279 gui_scrollbar_draw(display, 0, y_start, SCROLLBAR_WIDTH-1, 303 gui_scrollbar_draw(display, 0, y_start, SCROLLBAR_WIDTH-1,
280 scrollbar_y_end - y_start, gui_list->nb_items, 304 scrollbar_y_end - y_start, gui_list->nb_items,
281 gui_list->start_item, 305 gui_list->start_item,
282 gui_list->start_item + display->nb_lines, VERTICAL); 306 gui_list->start_item + display->nb_lines, VERTICAL);
283 } 307 }
308 if (gui_list->title)
309 {
310 int start = ((display->width/display->char_width) - strlen(gui_list->title))/2;
311 display->puts(start, 0, gui_list->title);
312 }
313#else /* char cell display */
314 if (gui_list->title)
315 display->puts(0, 0, gui_list->title); /* dont center title */
284#endif 316#endif
285 gui_textarea_update(display); 317 gui_textarea_update(display);
286} 318}
@@ -307,9 +339,11 @@ void gui_list_select_next(struct gui_list * gui_list)
307 { 339 {
308 gui_list->selected_item+=gui_list->selected_size; 340 gui_list->selected_item+=gui_list->selected_size;
309 int nb_lines = gui_list->display->nb_lines; 341 int nb_lines = gui_list->display->nb_lines;
342 if (gui_list->title)
343 nb_lines--;
310 int item_pos = gui_list->selected_item - gui_list->start_item; 344 int item_pos = gui_list->selected_item - gui_list->start_item;
311 int end_item = gui_list->start_item + nb_lines; 345 int end_item = gui_list->start_item + nb_lines;
312 346
313 if (global_settings.scroll_paginated) 347 if (global_settings.scroll_paginated)
314 { 348 {
315 /* When we reach the bottom of the list 349 /* When we reach the bottom of the list
@@ -336,7 +370,9 @@ void gui_list_select_previous(struct gui_list * gui_list)
336{ 370{
337 if( gui_list->selected_item-gui_list->selected_size < 0 ) 371 if( gui_list->selected_item-gui_list->selected_size < 0 )
338 { 372 {
339 int nb_lines = gui_list->display->nb_lines; 373 int nb_lines = gui_list->display->nb_lines;
374 if (gui_list->title)
375 nb_lines--;
340 if(gui_list->limit_scroll) 376 if(gui_list->limit_scroll)
341 return; 377 return;
342 /* we have aleady reached the top of the list */ 378 /* we have aleady reached the top of the list */
@@ -384,6 +420,8 @@ void gui_list_select_next_page(struct gui_list * gui_list, int nb_lines)
384 } 420 }
385 else 421 else
386 { 422 {
423 if (gui_list->title)
424 nb_lines--;
387 nb_lines-=nb_lines%gui_list->selected_size; 425 nb_lines-=nb_lines%gui_list->selected_size;
388 gui_list->selected_item += nb_lines; 426 gui_list->selected_item += nb_lines;
389 if(gui_list->selected_item > gui_list->nb_items-1) 427 if(gui_list->selected_item > gui_list->nb_items-1)
@@ -402,6 +440,8 @@ void gui_list_select_previous_page(struct gui_list * gui_list, int nb_lines)
402 } 440 }
403 else 441 else
404 { 442 {
443 if (gui_list->title)
444 nb_lines--;
405 nb_lines-=nb_lines%gui_list->selected_size; 445 nb_lines-=nb_lines%gui_list->selected_size;
406 gui_list->selected_item -= nb_lines; 446 gui_list->selected_item -= nb_lines;
407 if(gui_list->selected_item < 0) 447 if(gui_list->selected_item < 0)
@@ -473,7 +513,10 @@ void gui_list_screen_scroll_out_of_view(bool enable)
473 offset_out_of_view = false; 513 offset_out_of_view = false;
474} 514}
475#endif /* HAVE_LCD_BITMAP */ 515#endif /* HAVE_LCD_BITMAP */
476 516void gui_list_set_title(struct gui_list *gui_list , char* title)
517{
518 gui_list->title = title;
519}
477/* 520/*
478 * Synchronized lists stuffs 521 * Synchronized lists stuffs
479 */ 522 */
@@ -590,6 +633,13 @@ void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll)
590 gui_list_limit_scroll(&(lists->gui_list[i]), scroll); 633 gui_list_limit_scroll(&(lists->gui_list[i]), scroll);
591} 634}
592 635
636void gui_synclist_set_title(struct gui_synclist * lists, char* title)
637{
638 int i;
639 FOR_NB_SCREENS(i)
640 gui_list_set_title(&(lists->gui_list[i]), title);
641}
642
593void gui_synclist_flash(struct gui_synclist * lists) 643void gui_synclist_flash(struct gui_synclist * lists)
594{ 644{
595 int i; 645 int i;
diff --git a/apps/gui/list.h b/apps/gui/list.h
index f0a6d3f32c..447e0d832d 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -168,6 +168,8 @@ struct gui_list
168 int selected_size; 168 int selected_size;
169 /* The data that will be passed to the callback function YOU implement */ 169 /* The data that will be passed to the callback function YOU implement */
170 void * data; 170 void * data;
171 /* The optional title, set to NULL for none */
172 char *title;
171}; 173};
172 174
173/* 175/*
@@ -332,7 +334,10 @@ extern void gui_list_del_item(struct gui_list * gui_list);
332 */ 334 */
333extern void gui_list_flash(struct gui_list * gui_list); 335extern void gui_list_flash(struct gui_list * gui_list);
334 336
335 337/*
338 * Set the title of the list, setting to NULL disables the title
339 */
340extern void gui_list_set_title(struct gui_list *gui_list , char* title);
336/* 341/*
337 * This part handles as many lists as there are connected screens 342 * This part handles as many lists as there are connected screens
338 * (the api is similar to the ones above) 343 * (the api is similar to the ones above)
@@ -373,6 +378,7 @@ extern void gui_synclist_add_item(struct gui_synclist * lists);
373extern void gui_synclist_del_item(struct gui_synclist * lists); 378extern void gui_synclist_del_item(struct gui_synclist * lists);
374extern void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll); 379extern void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll);
375extern void gui_synclist_flash(struct gui_synclist * lists); 380extern void gui_synclist_flash(struct gui_synclist * lists);
381extern void gui_synclist_set_title(struct gui_synclist * lists, char* title);
376void gui_synclist_scroll_right(struct gui_synclist * lists); 382void gui_synclist_scroll_right(struct gui_synclist * lists);
377void gui_synclist_scroll_left(struct gui_synclist * lists); 383void gui_synclist_scroll_left(struct gui_synclist * lists);
378 384
diff --git a/apps/settings.c b/apps/settings.c
index bb550ac929..1f8f15be1e 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -68,7 +68,6 @@
68#include "sound.h" 68#include "sound.h"
69#include "rbunicode.h" 69#include "rbunicode.h"
70#include "dircache.h" 70#include "dircache.h"
71#include "select.h"
72#include "statusbar.h" 71#include "statusbar.h"
73#include "splash.h" 72#include "splash.h"
74#include "list.h" 73#include "list.h"
@@ -1852,113 +1851,154 @@ void talk_unit(int unit, int value)
1852 } 1851 }
1853} 1852}
1854 1853
1855bool set_int(const unsigned char* string, 1854struct value_setting_data {
1856 const char* unit, 1855 enum optiontype type;
1857 int voice_unit, 1856 /* used for "value" settings.. */
1858 int* variable, 1857 int max;
1859 void (*function)(int), 1858 int step;
1860 int step, 1859 int voice_unit;
1861 int min, 1860 const char * unit;
1862 int max, 1861 void (*formatter)(char* dest, int dest_length,
1863 void (*formatter)(char*, int, int, const char*) ) 1862 int variable, const char* unit);
1863 /* used for BOOL and "choice" settings */
1864 struct opt_items* options;
1865};
1866
1867char * value_setting_get_name_cb(int selected_item,void * data, char *buffer)
1864{ 1868{
1865 int button; 1869 struct value_setting_data* cb_data =
1866 int oldvalue=*variable; 1870 (struct value_setting_data*)data;
1867 struct gui_select select; 1871 if (cb_data->type == INT && !cb_data->options)
1868 gui_select_init_numeric(&select, (char *)string, *variable, min, max, step, unit,
1869 formatter);
1870 gui_syncselect_draw(&select);
1871 talk_unit(voice_unit, *variable);
1872 while (!select.validated)
1873 { 1872 {
1874 button = button_get_w_tmo(HZ/2); 1873 int item = cb_data->max -(selected_item*cb_data->step);
1875 if(gui_syncselect_do_button(&select, button)) 1874 if (cb_data->formatter)
1876 { 1875 cb_data->formatter(buffer, MAX_PATH,item,cb_data->unit);
1877 *variable=select.options.option; 1876 else
1878 gui_syncselect_draw(&select); 1877 snprintf(buffer, MAX_PATH,"%d %s",item,cb_data->unit);
1879 talk_unit(voice_unit, *variable);
1880 if ( function )
1881 function(*variable);
1882 }
1883 gui_syncstatusbar_draw(&statusbars, false);
1884 if(select.canceled)
1885 {
1886 *variable=oldvalue;
1887 if ( function )
1888 function(*variable);
1889 return false;
1890 }
1891 if(default_event_handler(button) == SYS_USB_CONNECTED)
1892 return true;
1893 } 1878 }
1894 return false; 1879 else strcpy(buffer,P2STR(cb_data->options[selected_item].string));
1895} 1880 return buffer;
1896 1881}
1897/* NOTE: the 'type' parameter specifies the actual type of the variable
1898 that 'variable' points to. not the value within. Only variables with
1899 type 'bool' should use parameter BOOL.
1900
1901 The type separation is necessary since int and bool are fundamentally
1902 different and bit-incompatible types and can not share the same access
1903 code. */
1904
1905#define set_type_fromint(type, dest, value) \
1906 if (type == INT) \
1907 *(int *)dest=value; \
1908 else \
1909 *(bool *)dest=value?true:false
1910
1911#define type_fromvoidptr(type, value) \ 1882#define type_fromvoidptr(type, value) \
1912 (type == INT)? \ 1883 (type == INT)? \
1913 (int)(*(int*)(value)) \ 1884 (int)(*(int*)(value)) \
1914 : \ 1885 : \
1915 (bool)(*(bool*)(value)) 1886 (bool)(*(bool*)(value))
1916 1887bool do_set_setting(const unsigned char* string, void *variable,
1917#define get_int_fromtype(type, var) \ 1888 int nb_items,int selected,
1918 (type == INT)?*(int *)var:(*(bool *)var?1:0) 1889 struct value_setting_data *cb_data,
1919 1890 void (*function)(int))
1920bool set_option(const char* string, void* variable, enum optiontype type,
1921 const struct opt_items* options, int numoptions, void (*function)(int))
1922{ 1891{
1923 int button; 1892 int button;
1893 bool done = false;
1894 struct gui_synclist lists;
1924 int oldvalue; 1895 int oldvalue;
1925 /* oldvalue=*variable; */ 1896
1926 oldvalue=get_int_fromtype(type, variable); 1897 if (cb_data->type == INT)
1927 struct gui_select select; 1898 oldvalue = *(int*)variable;
1928 gui_select_init_items(&select, string, oldvalue, options, numoptions); 1899 else oldvalue = *(bool*)variable;
1929 gui_syncselect_draw(&select); 1900
1901 gui_synclist_init(&lists,value_setting_get_name_cb,(void*)cb_data,false,1);
1902 gui_synclist_set_title(&lists, (char*)string);
1903 gui_synclist_set_icon_callback(&lists,NULL);
1904 gui_synclist_set_nb_items(&lists,nb_items);
1905 gui_synclist_limit_scroll(&lists,true);
1906 gui_synclist_select_item(&lists, selected);
1907
1930 if (global_settings.talk_menu) 1908 if (global_settings.talk_menu)
1931 talk_id(options[select.options.option].voice_id, true);
1932
1933 while ( !select.validated )
1934 { 1909 {
1935 gui_syncstatusbar_draw(&statusbars, true); 1910 if (cb_data->type == INT && !cb_data->options)
1936 button = button_get_w_tmo(HZ/2); 1911 talk_unit(cb_data->voice_unit, *(int*)variable);
1937 select.options.limit_loop = false; 1912 else talk_id(cb_data->options[selected].voice_id, false);
1938 if(gui_syncselect_do_button(&select, button)) 1913 }
1914
1915 gui_synclist_draw(&lists);
1916 while (!done)
1917 {
1918
1919 button = button_get(true);
1920 if (button == BUTTON_NONE)
1921 continue;
1922
1923 if (gui_synclist_do_button(&lists,button))
1939 { 1924 {
1940 /* *variable = gui_select_get_selected(&select) */
1941 set_type_fromint(type, variable, select.options.option);
1942 gui_syncselect_draw(&select);
1943 if (global_settings.talk_menu) 1925 if (global_settings.talk_menu)
1944 talk_id(options[select.options.option].voice_id, false); 1926 {
1945 if ( function ) 1927 int value;
1946 function(type_fromvoidptr(type, variable)); 1928 if (cb_data->type == INT && !cb_data->options)
1929 {
1930 value = cb_data->max -
1931 gui_synclist_get_sel_pos(&lists)*cb_data->step;
1932 talk_unit(cb_data->voice_unit, value);
1933 }
1934 else
1935 {
1936 value = gui_synclist_get_sel_pos(&lists);
1937 talk_id(cb_data->options[value].voice_id, false);
1938 }
1939 }
1940 if (cb_data->type == INT && !cb_data->options)
1941 *(int*)variable = cb_data->max -
1942 gui_synclist_get_sel_pos(&lists)*cb_data->step;
1943 else if (cb_data->type == BOOL)
1944 *(bool*)variable = gui_synclist_get_sel_pos(&lists) ? true : false;
1945 else *(int*)variable = gui_synclist_get_sel_pos(&lists);
1946 }
1947 else if (button == SETTINGS_CANCEL)
1948 {
1949 gui_syncsplash(HZ/2,true,str(LANG_MENU_SETTING_CANCEL));
1950 if (cb_data->type == INT)
1951 *(int*)variable = oldvalue;
1952 else *(bool*)variable = (bool)oldvalue;
1953 done = true;
1947 } 1954 }
1948 gui_syncstatusbar_draw(&statusbars, false); 1955 else if (button == SETTINGS_OK)
1949 if(select.canceled)
1950 { 1956 {
1951 /* *variable=oldvalue; */ 1957 done = true;
1952 set_type_fromint(type, variable, oldvalue);
1953 if ( function )
1954 function(type_fromvoidptr(type, variable));
1955 return false;
1956 } 1958 }
1957 if(default_event_handler(button) == SYS_USB_CONNECTED) 1959 else if(default_event_handler(button) == SYS_USB_CONNECTED)
1958 return true; 1960 return true;
1961 gui_syncstatusbar_draw(&statusbars, false);
1962 if ( function )
1963 function(type_fromvoidptr(cb_data->type,variable));
1959 } 1964 }
1960 return false; 1965 return false;
1961} 1966}
1967bool set_int(const unsigned char* string,
1968 const char* unit,
1969 int voice_unit,
1970 int* variable,
1971 void (*function)(int),
1972 int step,
1973 int min,
1974 int max,
1975 void (*formatter)(char*, int, int, const char*) )
1976{
1977 struct value_setting_data data = {
1978 INT,max, step, voice_unit,unit,formatter,NULL };
1979 return do_set_setting(string,variable,(max-min)/step + 1,
1980 (max-*variable)/step, &data,function);
1981}
1982
1983/* NOTE: the 'type' parameter specifies the actual type of the variable
1984 that 'variable' points to. not the value within. Only variables with
1985 type 'bool' should use parameter BOOL.
1986
1987 The type separation is necessary since int and bool are fundamentally
1988 different and bit-incompatible types and can not share the same access
1989 code. */
1990bool set_option(const char* string, void* variable, enum optiontype type,
1991 const struct opt_items* options, int numoptions, void (*function)(int))
1992{
1993 struct value_setting_data data = {
1994 type,0, 0, 0,NULL,NULL,(struct opt_items*)options };
1995 int selected;
1996 if (type == BOOL)
1997 selected = *(bool*)variable ? 1 : 0;
1998 else selected = *(int*)variable;
1999 return do_set_setting(string,variable,numoptions,
2000 selected, &data,function);
2001}
1962 2002
1963#ifdef HAVE_RECORDING 2003#ifdef HAVE_RECORDING
1964/* This array holds the record timer interval lengths, in seconds */ 2004/* This array holds the record timer interval lengths, in seconds */
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 93c809d007..6a11e723b1 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -351,11 +351,14 @@ static bool flip_display(void)
351 */ 351 */
352static bool invert_cursor(void) 352static bool invert_cursor(void)
353{ 353{
354 return set_bool_options(str(LANG_INVERT_CURSOR), 354 bool type = global_settings.invert_cursor;
355 &global_settings.invert_cursor, 355 bool rc = set_bool_options(str(LANG_INVERT_CURSOR),
356 &type,
356 STR(LANG_INVERT_CURSOR_BAR), 357 STR(LANG_INVERT_CURSOR_BAR),
357 STR(LANG_INVERT_CURSOR_POINTER), 358 STR(LANG_INVERT_CURSOR_POINTER),
358 NULL); 359 NULL);
360 global_settings.invert_cursor = type;
361 return rc;
359} 362}
360 363
361#ifdef HAVE_LCD_COLOR 364#ifdef HAVE_LCD_COLOR