Index: apps/gui/bitmap/list.c =================================================================== --- apps/gui/bitmap/list.c (revision 18957) +++ apps/gui/bitmap/list.c (working copy) @@ -103,7 +103,12 @@ vp_text->drawmode, 0); return true; } - + +static bool right_align_line = false; +void gui_synclist_set_right_aligned_line(bool right_align) +{ + right_align_line = right_align; +} void list_draw(struct screen *display, struct viewport *parent, struct gui_synclist *list) { @@ -178,6 +183,7 @@ char entry_buffer[MAX_PATH]; unsigned char *entry_name; int text_pos = 0; + right_align_line = false; s = list->callback_get_item_name(i, list->data, entry_buffer, sizeof(entry_buffer)); entry_name = P2STR(s); @@ -240,8 +246,26 @@ if (item_offset > item_width - (list_text[display->screen_type].width - text_pos)) { /* don't scroll */ - display->puts_style_offset(0, i-start, entry_name, - list_text[display->screen_type].drawmode, item_offset); + if (right_align_line) + { + struct viewport vp = list_text[display->screen_type]; + vp.height = font_get(vp.font)->height; + vp.width = item_width; + vp.x += (list_text[display->screen_type].width - item_width); + vp.y += (i-start)*vp.height; + /* get the selectoin bar happening */ + display->puts_style_offset(0, i-start, " ", + list_text[display->screen_type].drawmode, 0); + display->set_viewport(&vp); + display->puts_style_offset(0, 0, entry_name, + vp.drawmode, 0); + display->set_viewport(&list_text[display->screen_type]); + } + else + { + display->puts_style_offset(0, i-start, entry_name, + list_text[display->screen_type].drawmode, item_offset); + } } else { @@ -249,6 +273,21 @@ list_text[display->screen_type].drawmode, item_offset); } } + else if (right_align_line) + { + struct viewport vp = list_text[display->screen_type]; + vp.height = font_get(vp.font)->height; + vp.width = item_width; + vp.x += (list_text[display->screen_type].width - item_width); + vp.y += (i-start)*vp.height; + /* get the selection bar happening */ + display->puts_style_offset(0, i-start, " ", + list_text[display->screen_type].drawmode, 0); + display->set_viewport(&vp); + display->puts_style_offset(0, 0, entry_name, + vp.drawmode, 0); + display->set_viewport(&list_text[display->screen_type]); + } else { if (list->scroll_all) Index: apps/gui/list.c =================================================================== --- apps/gui/list.c (revision 18957) +++ apps/gui/list.c (working copy) @@ -157,6 +157,7 @@ gui_list->data=data; gui_list->scroll_all=scroll_all; gui_list->selected_size=selected_size; + gui_list->movement_size = selected_size; gui_list->title = NULL; gui_list->title_width = 0; gui_list->title_icon = Icon_NOICON; @@ -259,7 +260,7 @@ nb_lines = viewport_get_nb_lines(&vp); /* edge case,, selected last item */ - if (gui_list->selected_item == gui_list->nb_items -1) + if (gui_list->selected_item == gui_list->nb_items - 1) { gui_list->start_item[screen] = MAX(0, gui_list->nb_items - nb_lines); } @@ -318,6 +319,7 @@ int i; if( item_number > gui_list->nb_items-1 || item_number < 0 ) return; + gui_list->selected_item = item_number; FOR_NB_SCREENS(i) gui_list_put_selection_on_screen(gui_list, i); @@ -327,22 +329,31 @@ int offset) { int new_selection; + int last_item = gui_list->nb_items - gui_list->selected_size; if (gui_list->selected_size > 1) { - offset *= gui_list->selected_size; + offset *= gui_list->movement_size; /* always select the first item of multi-line lists */ - offset -= offset%gui_list->selected_size; + offset -= offset%gui_list->movement_size; } new_selection = gui_list->selected_item + offset; - if (new_selection >= gui_list->nb_items) + + if (new_selection > last_item) { + new_selection = gui_list->nb_items - gui_list->movement_size; + if (gui_list->selected_size > gui_list->movement_size && + new_selection > gui_list->nb_items - gui_list->selected_size) + new_selection = gui_list->nb_items - gui_list->selected_size; + gui_list->selected_item = gui_list->limit_scroll ? - gui_list->nb_items - gui_list->selected_size : 0; + new_selection : 0; } else if (new_selection < 0) { - gui_list->selected_item = gui_list->limit_scroll ? - 0 : gui_list->nb_items - gui_list->selected_size; + if (gui_list->limit_scroll) + gui_list->selected_item = 0; + else + gui_list->selected_item = gui_list->nb_items - gui_list->selected_size; } else if (gui_list->show_selection_marker == false) { @@ -361,13 +372,13 @@ if (screen_top < 0) screen_top = 0; gui_list->start_item[i] = MIN(screen_top, gui_list->start_item[i] + - gui_list->selected_size); + gui_list->movement_size); gui_list->selected_item = gui_list->start_item[i]; } else { gui_list->start_item[i] = MAX(0, gui_list->start_item[i] - - gui_list->selected_size); + gui_list->movement_size); gui_list->selected_item = gui_list->start_item[i] + nb_lines; } } Index: apps/gui/list.h =================================================================== --- apps/gui/list.h (revision 18957) +++ apps/gui/list.h (working copy) @@ -64,6 +64,8 @@ * - buffer_len : length of the buffer * Returns a pointer to a string that contains the text to display */ + /* tells the list to draw the next line on the right of the screen */ +void gui_synclist_set_right_aligned_line(bool right_align); typedef char * list_get_name(int selected_item, void * data, char * buffer, size_t buffer_len); /* @@ -100,6 +102,9 @@ int start_item[NB_SCREENS]; /* the item that is displayed at the top of the screen */ /* the number of lines that are selected at the same time */ int selected_size; + /* the number of items to jump when the selection changes. + by default set to selected_size */ + int movement_size; /* These are used to calculate how much of the screen content we need to redraw. */ int last_displayed_selected_item; Index: apps/menu.c =================================================================== --- apps/menu.c (revision 18957) +++ apps/menu.c (working copy) @@ -71,7 +71,7 @@ static int current_subitems[MAX_MENU_SUBITEMS]; static int current_subitems_count = 0; static int talk_menu_item(int selected_item, void *data); - +static struct gui_synclist *menulists; static void get_menu_callback(const struct menu_item_ex *m, menu_callback_type *menu_callback) { @@ -96,6 +96,22 @@ return i; return 0; } +bool menu_has_settings(const struct menu_item_ex *menu) +{ + unsigned int i, t; + const struct menu_item_ex *submenu; + for (i=0;iflags);i++) + { + submenu = menu->submenus[i]; + t = (submenu->flags&MENU_TYPE_MASK); + if (t == MT_SETTING || + t == MT_SETTING_W_TEXT) + return true; + } + return false; +} + +bool show_info_line = false; static char * get_menu_item_name(int selected_item, void * data, char *buffer, @@ -103,7 +119,26 @@ { const struct menu_item_ex *menu = (const struct menu_item_ex *)data; int type = (menu->flags&MENU_TYPE_MASK); - selected_item = get_menu_selection(selected_item, menu); + int menu_selection = gui_synclist_get_sel_pos(menulists); + if (show_info_line && selected_item <= menu_selection) + selected_item = get_menu_selection(selected_item, menu); + else if (show_info_line && selected_item == menu_selection + 1) + { + menu = menu->submenus[selected_item-1]; + type = (menu->flags&MENU_TYPE_MASK); + gui_synclist_set_right_aligned_line(true); + if (type == MT_SETTING_W_TEXT || + type == MT_SETTING) + { + const struct settings_list *setting = find_setting(menu->variable, NULL); + return option_get_valuestring(setting, + buffer, buffer_len, + option_value_as_int(setting)); + } + return "---->"; + } + else + selected_item = get_menu_selection(selected_item-(show_info_line?1:0), menu); (void)buffer_len; /* only MT_MENU or MT_RETURN_ID is allowed in here */ @@ -137,7 +172,13 @@ { const struct menu_item_ex *menu = (const struct menu_item_ex *)data; int menu_icon = Icon_NOICON; - selected_item = get_menu_selection(selected_item, menu); + int menu_selection = gui_synclist_get_sel_pos(menulists); + if (show_info_line && selected_item <= menu_selection) + selected_item = get_menu_selection(selected_item, menu); + else if (show_info_line && selected_item == menu_selection + 1) + return Icon_NOICON; + else + selected_item = get_menu_selection(selected_item-(show_info_line?1:0), menu); if ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID) { @@ -204,8 +245,9 @@ } } current_submenus_menu = (struct menu_item_ex *)menu; - - gui_synclist_init(lists,get_menu_item_name,(void*)menu,false,1, parent); + show_info_line = menu_has_settings(menu); + gui_synclist_init(lists,get_menu_item_name,(void*)menu,false,show_info_line?2:1, parent); + lists->movement_size = 1; #ifdef HAVE_LCD_BITMAP if (menu->callback_and_desc->icon_id == Icon_NOICON) icon = Icon_Submenu_Entered; @@ -219,7 +261,7 @@ #endif if(global_settings.talk_menu) gui_synclist_set_voice_callback(lists, talk_menu_item); - gui_synclist_set_nb_items(lists,current_subitems_count); + gui_synclist_set_nb_items(lists,current_subitems_count+(show_info_line?1:0)); gui_synclist_limit_scroll(lists,true); gui_synclist_select_item(lists, find_menu_selection(selected)); @@ -392,6 +434,7 @@ gui_buttonbar_set(&buttonbar, "<<<", "", ""); #endif + menulists = &lists; menu_callback_type menu_callback = NULL; if (start_menu == NULL) menu = &main_menu_;