Index: apps/tree.c =================================================================== --- apps/tree.c (revision 16430) +++ apps/tree.c (working copy) @@ -311,8 +311,7 @@ gui_synclist_set_voice_callback(&tree_lists, tree_voice_cb); gui_synclist_set_icon_callback(&tree_lists, &tree_get_fileicon); #ifdef HAVE_LCD_COLOR - gui_list_set_color_callback(&tree_lists, - &tree_get_filecolor); + gui_synclist_set_color_callback(&tree_lists, &tree_get_filecolor); #endif } Index: apps/settings.c =================================================================== --- apps/settings.c (revision 16430) +++ apps/settings.c (working copy) @@ -951,7 +951,7 @@ if (global_settings.colors_file[0]) read_color_theme_file(); #endif - + list_init_viewports(); } Index: apps/gui/list.c =================================================================== --- apps/gui/list.c (revision 16430) +++ apps/gui/list.c (working copy) @@ -37,6 +37,7 @@ #include "sound.h" #include "misc.h" #include "talk.h" +#include "viewport.h" #ifdef HAVE_LCD_CHARCELLS #define SCROLL_LIMIT 1 @@ -56,12 +57,64 @@ #endif static struct gui_synclist* last_list_displayed; -#define SHOW_LIST_TITLE ((gui_list->title != NULL) && \ - (display->nb_lines > 2)) - static void gui_list_select_at_offset(struct gui_synclist * gui_list, int offset); +void list_draw(struct screen *display, struct viewport *parent, struct gui_synclist *list); +#ifdef HAVE_LCD_BITMAP +static struct viewport parent[NB_SCREENS]; +void list_init_viewports(void) +{ + int i; + struct viewport *vp; + FOR_NB_SCREENS(i) + { + vp = &parent[i]; + viewport_set_defaults(vp, i); + if (i == SCREEN_MAIN) + { + if (global_settings.list_vp_config[0]) + { + viewport_load_config(global_settings.list_vp_config, vp); + } + } +#if NB_SCREENS > 1 + else + { + + if (global_settings.remote_list_vp_config[0]) + { + viewport_load_config(global_settings.remote_list_vp_config, vp); + } + } +#endif + } +} +#else +static struct viewport parent[NB_SCREENS] = +{ + [SCREEN_MAIN] = + { + .x = 0, + .y = 0, + .width = LCD_WIDTH, + .height = LCD_HEIGHT + }, +}; +void list_init_viewports(void) +{ +} +#endif + +#ifdef HAVE_LCD_BITMAP +bool list_display_title(struct gui_synclist *list, struct viewport *vp) +{ + return list->title != NULL && viewport_get_nb_lines(vp)>2; +} +#else +#define list_display_title(l,v) false +#endif + /* * Initializes a scrolling list * - gui_list : the list structure to initialize @@ -82,7 +135,7 @@ gui_list->callback_get_item_icon = NULL; gui_list->callback_get_item_name = callback_get_item_name; gui_list->callback_speak_item = NULL; - gui_list_set_nb_items(gui_list, 0); + gui_list->nb_items = 0; gui_list->selected_item = 0; FOR_NB_SCREENS(i) { @@ -91,6 +144,7 @@ #ifdef HAVE_LCD_BITMAP gui_list->offset_position[i] = 0; #endif + gui_list->parent[i] = &parent[i]; } gui_list->limit_scroll = false; gui_list->data=data; @@ -118,8 +172,10 @@ #ifdef HAVE_LCD_BITMAP -static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width, - int text_pos, struct screen * display) +int list_title_height(struct gui_synclist *list, struct viewport *vp); + +int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width, + int text_pos, struct screen * display, struct viewport *vp) { int item_offset; @@ -130,7 +186,7 @@ else { /* if text is smaller then view */ - if (item_width <= display->width - text_pos) + if (item_width <= vp->width - text_pos) { item_offset = 0; } @@ -138,8 +194,8 @@ { /* if text got out of view */ if (gui_list->offset_position[display->screen_type] > - item_width - (display->width - text_pos)) - item_offset = item_width - (display->width - text_pos); + item_width - (vp->width - text_pos)) + item_offset = item_width - (vp->width - text_pos); else item_offset = gui_list->offset_position[display->screen_type]; } @@ -148,341 +204,32 @@ return item_offset; } #endif - /* - * Draws the list on the attached screen - * - gui_list : the list structure - */ -static void gui_list_draw_smart(struct gui_synclist *gui_list, struct screen * display) -{ - int text_pos; - bool draw_icons = (gui_list->callback_get_item_icon != NULL && global_settings.show_icons); - bool draw_cursor; - int i; - int lines; - static int last_lines[NB_SCREENS] = {0}; -#ifdef HAVE_LCD_BITMAP - int item_offset; - int old_margin = display->getxmargin(); -#endif - int start, end; - bool partial_draw = false; - -#ifdef HAVE_LCD_BITMAP - display->setfont(FONT_UI); - gui_textarea_update_nblines(display); -#endif - /* Speed up UI by drawing the changed contents only. */ - if (gui_list == last_list_displayed - && gui_list->last_displayed_start_item[display->screen_type] == gui_list->start_item[display->screen_type] - && gui_list->selected_size == 1) - { - partial_draw = true; - } - - lines = display->nb_lines - SHOW_LIST_TITLE; - if (last_lines[display->screen_type] != lines) - { - gui_list_select_at_offset(gui_list, 0); - last_lines[display->screen_type] = lines; - } - - if (partial_draw) - { - end = gui_list->last_displayed_selected_item - gui_list->start_item[display->screen_type]; - i = gui_list->selected_item - gui_list->start_item[display->screen_type]; - if (i < end ) - { - start = i; - end++; - } - else - { - start = end; - end = i + 1; - } - } - else - { - gui_textarea_clear(display); - start = 0; - end = display->nb_lines; - gui_list->last_displayed_start_item[display->screen_type] = gui_list->start_item[display->screen_type]; - last_list_displayed = gui_list; - } - - gui_list->last_displayed_selected_item = gui_list->selected_item; - - /* position and draw the list title & icon */ - if (SHOW_LIST_TITLE && !partial_draw) - { - if (gui_list->title_icon != NOICON && draw_icons) - { - screen_put_icon(display, 0, 0, gui_list->title_icon); -#ifdef HAVE_LCD_BITMAP - text_pos = get_icon_width(display->screen_type)+2; /* pixels */ -#else - text_pos = 1; /* chars */ -#endif - } - else - { - text_pos = 0; - } - -#ifdef HAVE_LCD_BITMAP - int title_style = STYLE_DEFAULT; -#ifdef HAVE_LCD_COLOR - if (gui_list->title_color >= 0) - { - title_style |= STYLE_COLORED; - title_style |= gui_list->title_color; - } -#endif - screen_set_xmargin(display, text_pos); /* margin for title */ - item_offset = gui_list_get_item_offset(gui_list, gui_list->title_width, - text_pos, display); - if (item_offset > gui_list->title_width - (display->width - text_pos)) - display->puts_style_offset(0, 0, gui_list->title, - title_style, item_offset); - else - display->puts_scroll_style_offset(0, 0, gui_list->title, - title_style, item_offset); -#else - display->puts_scroll(text_pos, 0, gui_list->title); -#endif - } - - /* Adjust the position of icon, cursor, text for the list */ -#ifdef HAVE_LCD_BITMAP - gui_textarea_update_nblines(display); - bool draw_scrollbar; - - draw_scrollbar = (global_settings.scrollbar && - lines < gui_list->nb_items); - - draw_cursor = !global_settings.cursor_style && - gui_list->show_selection_marker; - text_pos = 0; /* here it's in pixels */ - if(draw_scrollbar || SHOW_LIST_TITLE) /* indent if there's - a title */ - { - text_pos += SCROLLBAR_WIDTH; - } - if(draw_cursor) - text_pos += get_icon_width(display->screen_type) + 2; - - if(draw_icons) - text_pos += get_icon_width(display->screen_type) + 2; -#else - draw_cursor = true; - if(draw_icons) - text_pos = 2; /* here it's in chars */ - else - text_pos = 1; -#endif - -#ifdef HAVE_LCD_BITMAP - screen_set_xmargin(display, text_pos); /* margin for list */ -#endif - - if (SHOW_LIST_TITLE) - { - start++; - if (end < display->nb_lines) - end++; - } - -#ifdef HAVE_LCD_COLOR - unsigned char cur_line = 0; -#endif - for (i = start; i < end; i++) - { - unsigned char *s; - char entry_buffer[MAX_PATH]; - unsigned char *entry_name; - int current_item = gui_list->start_item[display->screen_type] + - (SHOW_LIST_TITLE ? i-1 : i); - - /* When there are less items to display than the - * current available space on the screen, we stop*/ - if(current_item >= gui_list->nb_items) - break; - s = gui_list->callback_get_item_name(current_item, - gui_list->data, - entry_buffer); - entry_name = P2STR(s); - -#ifdef HAVE_LCD_BITMAP - int style = STYLE_DEFAULT; - /* position the string at the correct offset place */ - int item_width,h; - display->getstringsize(entry_name, &item_width, &h); - item_offset = gui_list_get_item_offset(gui_list, item_width, - text_pos, display); -#endif - -#ifdef HAVE_LCD_COLOR - /* if the list has a color callback */ - if (gui_list->callback_get_item_color) - { - int color = gui_list->callback_get_item_color(current_item, - gui_list->data); - /* if color selected */ - if (color >= 0) - { - style |= STYLE_COLORED; - style |= color; - } - } -#endif - - if(gui_list->show_selection_marker && - current_item >= gui_list->selected_item && - current_item < gui_list->selected_item + gui_list->selected_size) - {/* The selected item must be displayed scrolling */ -#ifdef HAVE_LCD_BITMAP - if (global_settings.cursor_style == 1 -#ifdef HAVE_REMOTE_LCD - || display->screen_type == SCREEN_REMOTE -#endif - ) - { - /* Display inverted-line-style */ - style |= STYLE_INVERT; - } -#ifdef HAVE_LCD_COLOR - else if (global_settings.cursor_style == 2) - { - /* Display colour line selector */ - style |= STYLE_COLORBAR; - } - else if (global_settings.cursor_style == 3) - { - /* Display gradient line selector */ - style = STYLE_GRADIENT; - - /* Make the lcd driver know how many lines the gradient should - cover and current line number */ - /* number of selected lines */ - style |= NUMLN_PACK(gui_list->selected_size); - /* current line number, zero based */ - style |= CURLN_PACK(cur_line); - cur_line++; - } -#endif - else /* if (!global_settings.cursor_style) */ - { - if (current_item % gui_list->selected_size != 0) - draw_cursor = false; - } - /* if the text is smaller than the viewport size */ - if (item_offset > item_width - (display->width - text_pos)) - { - /* don't scroll */ - display->puts_style_offset(0, i, entry_name, - style, item_offset); - } - else - { - display->puts_scroll_style_offset(0, i, entry_name, - style, item_offset); - } -#else - display->puts_scroll(text_pos, i, entry_name); -#endif - - if (draw_cursor) - { - screen_put_icon_with_offset(display, 0, i, - (draw_scrollbar || SHOW_LIST_TITLE)? - SCROLLBAR_WIDTH: 0, - 0, Icon_Cursor); - } - } - else - {/* normal item */ - if(gui_list->scroll_all) - { -#ifdef HAVE_LCD_BITMAP - display->puts_scroll_style_offset(0, i, entry_name, - style, item_offset); -#else - display->puts_scroll(text_pos, i, entry_name); -#endif - } - else - { -#ifdef HAVE_LCD_BITMAP - display->puts_style_offset(0, i, entry_name, - style, item_offset); -#else - display->puts(text_pos, i, entry_name); -#endif - } - } - /* Icons display */ - if(draw_icons) - { - enum themable_icons icon; - icon = gui_list->callback_get_item_icon(current_item, gui_list->data); - if(icon > Icon_NOICON) - { -#ifdef HAVE_LCD_BITMAP - int x = draw_cursor?1:0; - int x_off = (draw_scrollbar || SHOW_LIST_TITLE) ? SCROLLBAR_WIDTH: 0; - screen_put_icon_with_offset(display, x, i, - x_off, 0, icon); -#else - screen_put_icon(display, 1, i, icon); -#endif - } - } - } - -#ifdef HAVE_LCD_BITMAP - /* Draw the scrollbar if needed*/ - if(draw_scrollbar) - { - int y_start = gui_textarea_get_ystart(display); - if (SHOW_LIST_TITLE) - y_start += display->char_height; - int scrollbar_y_end = display->char_height * - 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[display->screen_type], - gui_list->start_item[display->screen_type] + lines, VERTICAL); - } - - screen_set_xmargin(display, old_margin); -#endif - - gui_textarea_update(display); -} - -/* * Force a full screen update. */ + void gui_synclist_draw(struct gui_synclist *gui_list) { int i; FOR_NB_SCREENS(i) { last_list_displayed = NULL; - gui_list_draw_smart(gui_list, &screens[i]); + list_draw(&screens[i], gui_list->parent[i], gui_list); } } - - /* sets up the list so the selection is shown correctly on the screen */ static void gui_list_put_selection_on_screen(struct gui_synclist * gui_list, enum screen_type screen) { - struct screen *display = &screens[screen]; - int nb_lines = display->nb_lines - SHOW_LIST_TITLE; + int nb_lines; int difference = gui_list->selected_item - gui_list->start_item[screen]; + struct viewport vp = *gui_list->parent[screen]; +#ifndef HVE_LCD_CHARCELL + if (list_display_title(gui_list, gui_list->parent[screen])) + vp.height -= list_title_height(gui_list,gui_list->parent[screen]); +#endif + nb_lines = viewport_get_nb_lines(&vp); /* edge case,, selected last item */ if (gui_list->selected_item == gui_list->nb_items -1) @@ -576,8 +323,12 @@ int i, nb_lines, screen_top; FOR_NB_SCREENS(i) { - struct screen *display = &screens[i]; - nb_lines = display->nb_lines - SHOW_LIST_TITLE; + struct viewport vp = *gui_list->parent[i]; +#ifndef HVE_LCD_CHARCELL + if (list_display_title(gui_list, gui_list->parent[i])) + vp.height -= list_title_height(gui_list,gui_list->parent[i]); +#endif + nb_lines = viewport_get_nb_lines(&vp); if (offset > 0) { screen_top = gui_list->nb_items-nb_lines; @@ -616,23 +367,12 @@ */ void gui_synclist_del_item(struct gui_synclist * gui_list) { - int i; if(gui_list->nb_items > 0) { if (gui_list->selected_item == gui_list->nb_items-1) gui_list->selected_item--; - FOR_NB_SCREENS(i) - { - gui_textarea_update_nblines(&screens[i]); - int nb_lines = screens[i].nb_lines; - int dist_start_from_end = gui_list->nb_items - - gui_list->start_item[i] - 1; - - /* scroll the list if needed */ - if( (dist_start_from_end < nb_lines) && (gui_list->start_item[i] != 0) ) - gui_list->start_item[i]--; - } gui_list->nb_items--; + gui_synclist_select_item(gui_list, gui_list->selected_item); } } @@ -707,6 +447,14 @@ lists->callback_speak_item = voice_callback; } +#ifdef HAVE_LCD_COLOR +void gui_synclist_set_color_callback(struct gui_synclist * lists, + list_get_color color_callback) +{ + lists->callback_get_item_color = color_callback; +} +#endif + static void gui_synclist_select_next_page(struct gui_synclist * lists, enum screen_type screen) { Index: apps/gui/list.h =================================================================== --- apps/gui/list.h (revision 16430) +++ apps/gui/list.h (working copy) @@ -123,59 +123,10 @@ int title_color; list_get_color *callback_get_item_color; #endif + struct viewport *parent[NB_SCREENS]; }; -/* - * Sets the numbers of items the list can currently display - * note that the list's context like the currently pointed item is resetted - * - gui_list : the list structure - * - nb_items : the numbers of items you want - */ -#define gui_list_set_nb_items(gui_list, nb) \ - (gui_list)->nb_items = nb -/* - * Returns the numbers of items currently in the list - * - gui_list : the list structure - */ -#define gui_list_get_nb_items(gui_list) \ - (gui_list)->nb_items - -/* - * Sets the icon callback function - * - gui_list : the list structure - * - _callback : the callback function - */ -#define gui_list_set_icon_callback(gui_list, _callback) \ - (gui_list)->callback_get_item_icon=_callback - -/* - * Sets the voice callback function - * - gui_list : the list structure - * - _callback : the callback function - */ -#define gui_list_set_voice_callback(gui_list, _callback) \ - (gui_list)->callback_speak_item=_callback - -#ifdef HAVE_LCD_COLOR -/* - * Sets the color callback function - * - gui_list : the list structure - * - _callback : the callback function - */ -#define gui_list_set_color_callback(gui_list, _callback) \ - (gui_list)->callback_get_item_color=_callback -#endif - -/* - * Gives the position of the selected item - * - gui_list : the list structure - * Returns the position - */ -#define gui_list_get_sel_pos(gui_list) \ - (gui_list)->selected_item - - #ifdef HAVE_LCD_BITMAP /* parse global setting to static int */ extern void gui_list_screen_scroll_step(int ofs); @@ -183,17 +134,8 @@ /* parse global setting to static bool */ extern void gui_list_screen_scroll_out_of_view(bool enable); #endif /* HAVE_LCD_BITMAP */ -/* - * Tells the list wether it should stop when reaching the top/bottom - * or should continue (by going to bottom/top) - * - gui_list : the list structure - * - scroll : - * - true : stops when reaching top/bottom - * - false : continues to go to bottom/top when reaching top/bottom - */ -#define gui_list_limit_scroll(gui_list, scroll) \ - (gui_list)->limit_scroll=scroll +void list_init_viewports(void); extern void gui_synclist_init( struct gui_synclist * lists, @@ -205,6 +147,9 @@ extern void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items); extern void gui_synclist_set_icon_callback(struct gui_synclist * lists, list_get_icon icon_callback); extern void gui_synclist_set_voice_callback(struct gui_synclist * lists, list_speak_item voice_callback); +#ifdef HAVE_LCD_COLOR +extern void gui_synclist_set_color_callback(struct gui_synclist * lists, list_get_color color_callback); +#endif extern void gui_synclist_speak_item(struct gui_synclist * lists); extern int gui_synclist_get_nb_items(struct gui_synclist * lists); Index: apps/settings.h =================================================================== --- apps/settings.h (revision 16430) +++ apps/settings.h (working copy) @@ -422,6 +422,10 @@ #endif unsigned char wps_file[MAX_FILENAME+1]; /* last wps */ unsigned char lang_file[MAX_FILENAME+1]; /* last language */ + unsigned char list_vp_config[MAX_PATH+1]; /* viewport file for the lists */ +#ifdef HAVE_REMOTE_LCD + unsigned char remote_list_vp_config[MAX_PATH+1]; /* viewport file for the lists */ +#endif /* misc options */ Index: apps/menus/display_menu.c =================================================================== --- apps/menus/display_menu.c (revision 16430) +++ apps/menus/display_menu.c (working copy) @@ -297,8 +297,20 @@ /***********************************/ /* BARS MENU */ #ifdef HAVE_LCD_BITMAP +int statusbar_callback(int action,const struct menu_item_ex *this_item) +{ + (void)this_item; + switch (action) + { + case ACTION_EXIT_MENUITEM: + /* this should be changed so only the viewports are reloaded */ + settings_apply(); + break; + } + return action; +} MENUITEM_SETTING(scrollbar_item, &global_settings.scrollbar, NULL); -MENUITEM_SETTING(statusbar, &global_settings.statusbar, NULL); +MENUITEM_SETTING(statusbar, &global_settings.statusbar, statusbar_callback); #if CONFIG_KEYPAD == RECORDER_PAD MENUITEM_SETTING(buttonbar, &global_settings.buttonbar, NULL); #endif Index: apps/settings_list.c =================================================================== --- apps/settings_list.c (revision 16430) +++ apps/settings_list.c (working copy) @@ -1232,6 +1232,12 @@ #endif /* CONFIG_CODEC == SWCODEC */ FILENAME_SETTING(0, playlist_catalog_dir, "playlist catalog directory", PLAYLIST_CATALOG_DEFAULT_DIR, NULL, NULL, MAX_FILENAME+1), + FILENAME_SETTING(F_THEMESETTING, list_vp_config, "list viewport", "", + NULL, NULL, MAX_PATH+1), +#ifdef HAVE_REMOTE_LCD + FILENAME_SETTING(F_THEMESETTING, remote_list_vp_config, "remote list viewport", "", + NULL, NULL, MAX_PATH+1), +#endif }; const int nb_settings = sizeof(settings)/sizeof(*settings); Index: apps/SOURCES =================================================================== --- apps/SOURCES (revision 16430) +++ apps/SOURCES (working copy) @@ -53,6 +53,11 @@ gui/icon.c #endif gui/list.c +#ifdef HAVE_LCD_BITMAP +gui/bitmap/list.c +#else +gui/charcell/list.c +#endif gui/option_select.c gui/quickscreen.c gui/scrollbar.c @@ -62,6 +67,7 @@ gui/yesno.c gui/wps_debug.c gui/wps_parser.c +gui/viewport.c #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) gui/backdrop.c Index: apps/main.c =================================================================== --- apps/main.c (revision 16430) +++ apps/main.c (working copy) @@ -125,7 +125,13 @@ static void app_main(void) #endif { + int i; init(); + FOR_NB_SCREENS(i) + { + screens[i].clear_display(); + screens[i].update(); + } tree_gui_init(); root_menu(); }