summaryrefslogtreecommitdiffstats
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.tar.bz2
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
gui/option_select.c
gui/quickscreen.c
gui/scrollbar.c
-gui/select.c
gui/splash.c
gui/statusbar.c
gui/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 @@
#include "font.h"
#include "button.h"
#include "sprintf.h"
+#include "string.h"
#include "settings.h"
#include "kernel.h"
@@ -66,6 +67,7 @@ void gui_list_init(struct gui_list * gui_list,
#endif
gui_list->scroll_all=scroll_all;
gui_list->selected_size=selected_size;
+ gui_list->title = NULL;
}
void 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,
#endif
gui_textarea_update_nblines(gui_list->display);
int nb_lines=gui_list->display->nb_lines;
+ if (gui_list->title)
+ nb_lines--;
if(put_from_end)
{
int list_end = gui_list->selected_item + SCROLL_LIMIT;
@@ -147,13 +151,28 @@ void gui_list_draw(struct gui_list * gui_list)
bool draw_icons = (gui_list->callback_get_item_icon != NULL ) ;
bool draw_cursor;
int i;
+ int lines;
/* Adjust the position of icon, cursor, text */
+ if (gui_list->title)
+ {
+ i = 1;
+ lines = display->nb_lines - 1;
+ }
+ else
+ {
+ i = 0;
+ lines = display->nb_lines;
+ }
#ifdef HAVE_LCD_BITMAP
display->setfont(FONT_UI);
gui_textarea_update_nblines(display);
- bool draw_scrollbar = (global_settings.scrollbar &&
- display->nb_lines < gui_list->nb_items);
+ bool draw_scrollbar;
+
+
+ draw_scrollbar = (global_settings.scrollbar &&
+ lines < gui_list->nb_items);
+
draw_cursor = !global_settings.invert_cursor;
text_pos = 0; /* here it's in pixels */
if(draw_scrollbar)
@@ -182,11 +201,12 @@ void gui_list_draw(struct gui_list * gui_list)
screen_set_xmargin(display, text_pos);
#endif
- for(i = 0;i < display->nb_lines;i++)
+
+ while (i < display->nb_lines)
{
char entry_buffer[MAX_PATH];
unsigned char *entry_name;
- int current_item = gui_list->start_item + i;
+ int current_item = gui_list->start_item + (gui_list->title?i-1:i);
/* When there are less items to display than the
* current available space on the screen, we stop*/
@@ -268,19 +288,31 @@ void gui_list_draw(struct gui_list * gui_list)
if(icon)
screen_put_iconxy(display, icon_pos, i, icon);
}
+ i++;
}
-#ifdef HAVE_LCD_BITMAP
+
+#ifdef HAVE_LCD_BITMAP
/* Draw the scrollbar if needed*/
if(draw_scrollbar)
{
int y_start = gui_textarea_get_ystart(display);
+ if (gui_list->title)
+ y_start += display->char_height;
int scrollbar_y_end = display->char_height *
- display->nb_lines + y_start;
+ lines + y_start;
gui_scrollbar_draw(display, 0, y_start, SCROLLBAR_WIDTH-1,
scrollbar_y_end - y_start, gui_list->nb_items,
gui_list->start_item,
gui_list->start_item + display->nb_lines, VERTICAL);
}
+ if (gui_list->title)
+ {
+ int start = ((display->width/display->char_width) - strlen(gui_list->title))/2;
+ display->puts(start, 0, gui_list->title);
+ }
+#else /* char cell display */
+ if (gui_list->title)
+ display->puts(0, 0, gui_list->title); /* dont center title */
#endif
gui_textarea_update(display);
}
@@ -307,9 +339,11 @@ void gui_list_select_next(struct gui_list * gui_list)
{
gui_list->selected_item+=gui_list->selected_size;
int nb_lines = gui_list->display->nb_lines;
+ if (gui_list->title)
+ nb_lines--;
int item_pos = gui_list->selected_item - gui_list->start_item;
int end_item = gui_list->start_item + nb_lines;
-
+
if (global_settings.scroll_paginated)
{
/* When we reach the bottom of the list
@@ -336,7 +370,9 @@ void gui_list_select_previous(struct gui_list * gui_list)
{
if( gui_list->selected_item-gui_list->selected_size < 0 )
{
- int nb_lines = gui_list->display->nb_lines;
+ int nb_lines = gui_list->display->nb_lines;
+ if (gui_list->title)
+ nb_lines--;
if(gui_list->limit_scroll)
return;
/* 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)
}
else
{
+ if (gui_list->title)
+ nb_lines--;
nb_lines-=nb_lines%gui_list->selected_size;
gui_list->selected_item += nb_lines;
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)
}
else
{
+ if (gui_list->title)
+ nb_lines--;
nb_lines-=nb_lines%gui_list->selected_size;
gui_list->selected_item -= nb_lines;
if(gui_list->selected_item < 0)
@@ -473,7 +513,10 @@ void gui_list_screen_scroll_out_of_view(bool enable)
offset_out_of_view = false;
}
#endif /* HAVE_LCD_BITMAP */
-
+void gui_list_set_title(struct gui_list *gui_list , char* title)
+{
+ gui_list->title = title;
+}
/*
* Synchronized lists stuffs
*/
@@ -590,6 +633,13 @@ void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll)
gui_list_limit_scroll(&(lists->gui_list[i]), scroll);
}
+void gui_synclist_set_title(struct gui_synclist * lists, char* title)
+{
+ int i;
+ FOR_NB_SCREENS(i)
+ gui_list_set_title(&(lists->gui_list[i]), title);
+}
+
void gui_synclist_flash(struct gui_synclist * lists)
{
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
int selected_size;
/* The data that will be passed to the callback function YOU implement */
void * data;
+ /* The optional title, set to NULL for none */
+ char *title;
};
/*
@@ -332,7 +334,10 @@ extern void gui_list_del_item(struct gui_list * gui_list);
*/
extern void gui_list_flash(struct gui_list * gui_list);
-
+/*
+ * Set the title of the list, setting to NULL disables the title
+ */
+extern void gui_list_set_title(struct gui_list *gui_list , char* title);
/*
* This part handles as many lists as there are connected screens
* (the api is similar to the ones above)
@@ -373,6 +378,7 @@ extern void gui_synclist_add_item(struct gui_synclist * lists);
extern void gui_synclist_del_item(struct gui_synclist * lists);
extern void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll);
extern void gui_synclist_flash(struct gui_synclist * lists);
+extern void gui_synclist_set_title(struct gui_synclist * lists, char* title);
void gui_synclist_scroll_right(struct gui_synclist * lists);
void gui_synclist_scroll_left(struct gui_synclist * lists);
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 @@
#include "sound.h"
#include "rbunicode.h"
#include "dircache.h"
-#include "select.h"
#include "statusbar.h"
#include "splash.h"
#include "list.h"
@@ -1852,113 +1851,154 @@ void talk_unit(int unit, int value)
}
}
-bool set_int(const unsigned char* string,
- const char* unit,
- int voice_unit,
- int* variable,
- void (*function)(int),
- int step,
- int min,
- int max,
- void (*formatter)(char*, int, int, const char*) )
+struct value_setting_data {
+ enum optiontype type;
+ /* used for "value" settings.. */
+ int max;
+ int step;
+ int voice_unit;
+ const char * unit;
+ void (*formatter)(char* dest, int dest_length,
+ int variable, const char* unit);
+ /* used for BOOL and "choice" settings */
+ struct opt_items* options;
+};
+
+char * value_setting_get_name_cb(int selected_item,void * data, char *buffer)
{
- int button;
- int oldvalue=*variable;
- struct gui_select select;
- gui_select_init_numeric(&select, (char *)string, *variable, min, max, step, unit,
- formatter);
- gui_syncselect_draw(&select);
- talk_unit(voice_unit, *variable);
- while (!select.validated)
+ struct value_setting_data* cb_data =
+ (struct value_setting_data*)data;
+ if (cb_data->type == INT && !cb_data->options)
{
- button = button_get_w_tmo(HZ/2);
- if(gui_syncselect_do_button(&select, button))
- {
- *variable=select.options.option;
- gui_syncselect_draw(&select);
- talk_unit(voice_unit, *variable);
- if ( function )
- function(*variable);
- }
- gui_syncstatusbar_draw(&statusbars, false);
- if(select.canceled)
- {
- *variable=oldvalue;
- if ( function )
- function(*variable);
- return false;
- }
- if(default_event_handler(button) == SYS_USB_CONNECTED)
- return true;
+ int item = cb_data->max -(selected_item*cb_data->step);
+ if (cb_data->formatter)
+ cb_data->formatter(buffer, MAX_PATH,item,cb_data->unit);
+ else
+ snprintf(buffer, MAX_PATH,"%d %s",item,cb_data->unit);
}
- return false;
-}
-
-/* NOTE: the 'type' parameter specifies the actual type of the variable
- that 'variable' points to. not the value within. Only variables with
- type 'bool' should use parameter BOOL.
-
- The type separation is necessary since int and bool are fundamentally
- different and bit-incompatible types and can not share the same access
- code. */
-
-#define set_type_fromint(type, dest, value) \
- if (type == INT) \
- *(int *)dest=value; \
- else \
- *(bool *)dest=value?true:false
-
+ else strcpy(buffer,P2STR(cb_data->options[selected_item].string));
+ return buffer;
+}
#define type_fromvoidptr(type, value) \
(type == INT)? \
(int)(*(int*)(value)) \
: \
(bool)(*(bool*)(value))
-
-#define get_int_fromtype(type, var) \
- (type == INT)?*(int *)var:(*(bool *)var?1:0)
-
-bool set_option(const char* string, void* variable, enum optiontype type,
- const struct opt_items* options, int numoptions, void (*function)(int))
+bool do_set_setting(const unsigned char* string, void *variable,
+ int nb_items,int selected,
+ struct value_setting_data *cb_data,
+ void (*function)(int))
{
int button;
+ bool done = false;
+ struct gui_synclist lists;
int oldvalue;
- /* oldvalue=*variable; */
- oldvalue=get_int_fromtype(type, variable);
- struct gui_select select;
- gui_select_init_items(&select, string, oldvalue, options, numoptions);
- gui_syncselect_draw(&select);
+
+ if (cb_data->type == INT)
+ oldvalue = *(int*)variable;
+ else oldvalue = *(bool*)variable;
+
+ gui_synclist_init(&lists,value_setting_get_name_cb,(void*)cb_data,false,1);
+ gui_synclist_set_title(&lists, (char*)string);
+ gui_synclist_set_icon_callback(&lists,NULL);
+ gui_synclist_set_nb_items(&lists,nb_items);
+ gui_synclist_limit_scroll(&lists,true);
+ gui_synclist_select_item(&lists, selected);
+
if (global_settings.talk_menu)
- talk_id(options[select.options.option].voice_id, true);
-
- while ( !select.validated )
{
- gui_syncstatusbar_draw(&statusbars, true);
- button = button_get_w_tmo(HZ/2);
- select.options.limit_loop = false;
- if(gui_syncselect_do_button(&select, button))
+ if (cb_data->type == INT && !cb_data->options)
+ talk_unit(cb_data->voice_unit, *(int*)variable);
+ else talk_id(cb_data->options[selected].voice_id, false);
+ }
+
+ gui_synclist_draw(&lists);
+ while (!done)
+ {
+
+ button = button_get(true);
+ if (button == BUTTON_NONE)
+ continue;
+
+ if (gui_synclist_do_button(&lists,button))
{
- /* *variable = gui_select_get_selected(&select) */
- set_type_fromint(type, variable, select.options.option);
- gui_syncselect_draw(&select);
if (global_settings.talk_menu)
- talk_id(options[select.options.option].voice_id, false);
- if ( function )
- function(type_fromvoidptr(type, variable));
+ {
+ int value;
+ if (cb_data->type == INT && !cb_data->options)
+ {
+ value = cb_data->max -
+ gui_synclist_get_sel_pos(&lists)*cb_data->step;
+ talk_unit(cb_data->voice_unit, value);
+ }
+ else
+ {
+ value = gui_synclist_get_sel_pos(&lists);
+ talk_id(cb_data->options[value].voice_id, false);
+ }
+ }
+ if (cb_data->type == INT && !cb_data->options)
+ *(int*)variable = cb_data->max -
+ gui_synclist_get_sel_pos(&lists)*cb_data->step;
+ else if (cb_data->type == BOOL)
+ *(bool*)variable = gui_synclist_get_sel_pos(&lists) ? true : false;
+ else *(int*)variable = gui_synclist_get_sel_pos(&lists);
+ }
+ else if (button == SETTINGS_CANCEL)
+ {
+ gui_syncsplash(HZ/2,true,str(LANG_MENU_SETTING_CANCEL));
+ if (cb_data->type == INT)
+ *(int*)variable = oldvalue;
+ else *(bool*)variable = (bool)oldvalue;
+ done = true;
}
- gui_syncstatusbar_draw(&statusbars, false);
- if(select.canceled)
+ else if (button == SETTINGS_OK)
{
- /* *variable=oldvalue; */
- set_type_fromint(type, variable, oldvalue);
- if ( function )
- function(type_fromvoidptr(type, variable));
- return false;
+ done = true;
}
- if(default_event_handler(button) == SYS_USB_CONNECTED)
+ else if(default_event_handler(button) == SYS_USB_CONNECTED)
return true;
+ gui_syncstatusbar_draw(&statusbars, false);
+ if ( function )
+ function(type_fromvoidptr(cb_data->type,variable));
}
return false;
}
+bool set_int(const unsigned char* string,
+ const char* unit,
+ int voice_unit,
+ int* variable,
+ void (*function)(int),
+ int step,
+ int min,
+ int max,
+ void (*formatter)(char*, int, int, const char*) )
+{
+ struct value_setting_data data = {
+ INT,max, step, voice_unit,unit,formatter,NULL };
+ return do_set_setting(string,variable,(max-min)/step + 1,
+ (max-*variable)/step, &data,function);
+}
+
+/* NOTE: the 'type' parameter specifies the actual type of the variable
+ that 'variable' points to. not the value within. Only variables with
+ type 'bool' should use parameter BOOL.
+
+ The type separation is necessary since int and bool are fundamentally
+ different and bit-incompatible types and can not share the same access
+ code. */
+bool set_option(const char* string, void* variable, enum optiontype type,
+ const struct opt_items* options, int numoptions, void (*function)(int))
+{
+ struct value_setting_data data = {
+ type,0, 0, 0,NULL,NULL,(struct opt_items*)options };
+ int selected;
+ if (type == BOOL)
+ selected = *(bool*)variable ? 1 : 0;
+ else selected = *(int*)variable;
+ return do_set_setting(string,variable,numoptions,
+ selected, &data,function);
+}
#ifdef HAVE_RECORDING
/* 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)
*/
static bool invert_cursor(void)
{
- return set_bool_options(str(LANG_INVERT_CURSOR),
- &global_settings.invert_cursor,
+ bool type = global_settings.invert_cursor;
+ bool rc = set_bool_options(str(LANG_INVERT_CURSOR),
+ &type,
STR(LANG_INVERT_CURSOR_BAR),
STR(LANG_INVERT_CURSOR_POINTER),
NULL);
+ global_settings.invert_cursor = type;
+ return rc;
}
#ifdef HAVE_LCD_COLOR