diff --git a/apps/FILES b/apps/FILES index d08114dc3a..e4657013c5 100644 --- a/apps/FILES +++ b/apps/FILES @@ -40,6 +40,8 @@ codecs/spc/SOURCES codecs/Tremor/* eqs/*.cfg gui/*.[ch] +gui/charcell/*.[ch] +gui/bitmap/*.[ch] keymaps/*.[ch] lang/SOURCES lang/*.lang diff --git a/apps/SOURCES b/apps/SOURCES index e27e15d749..0d23f42765 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -54,6 +54,11 @@ gui/gwps-common.c 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 @@ -63,6 +68,7 @@ gui/textarea.c 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 diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c new file mode 100644 index 0000000000..63f24dd456 --- /dev/null +++ b/apps/gui/bitmap/list.c @@ -0,0 +1,276 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* This file contains the code to draw the list widget on BITMAP LCDs. */ + +#include "config.h" +#include "lcd.h" +#include "font.h" +#include "button.h" +#include "sprintf.h" +#include "string.h" +#include "settings.h" +#include "kernel.h" +#include "system.h" + +#include "action.h" +#include "screen_access.h" +#include "list.h" +#include "scrollbar.h" +#include "statusbar.h" +#include "textarea.h" +#include "lang.h" +#include "sound.h" +#include "misc.h" +#include "talk.h" +#include "viewport.h" + +#define SCROLLBAR_WIDTH 6 +#define ICON_PADDING 1 + +/* globals */ +struct viewport title_text[NB_SCREENS], title_icons[NB_SCREENS], + list_text[NB_SCREENS], list_icons[NB_SCREENS]; + +/* should probably be moved somewhere else */ +int list_title_height(struct gui_synclist *list, struct viewport *vp) +{ + (void)list; + return font_get(vp->font)->height; +} +int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width, + int text_pos, struct screen * display, + struct viewport *vp); +bool list_display_title(struct gui_synclist *list, struct viewport *vp); + +/* Draw the list... + internal screen layout: + ----------------- + |TI| title | TI is title icon + ----------------- + | | | | + |S|I| | S - scrollbar + | | | items | I - icons + | | | | + ------------------ +*/ +static bool draw_title(struct screen *display, struct viewport *parent, + struct gui_synclist *list) +{ + struct viewport *vp_icons = &title_icons[display->screen_type]; + struct viewport *vp_text = &title_text[display->screen_type]; + if (!list_display_title(list, parent)) + return false; + *vp_text = *parent; + vp_text->height = list_title_height(list, parent); + if (list->title_icon != Icon_NOICON && global_settings.show_icons) + { + *vp_icons = *vp_text; + vp_icons->width = get_icon_width(display->screen_type) + + ICON_PADDING*2; + vp_icons->x += ICON_PADDING; + + vp_text->width -= vp_icons->width + vp_icons->x; + vp_text->x += vp_icons->width + vp_icons->x; + + display->set_viewport(vp_icons); + screen_put_icon(display, 0, 0, list->title_icon); + } + display->set_viewport(vp_text); + vp_text->drawmode = STYLE_DEFAULT; +#ifdef HAVE_LCD_COLOR + if (list->title_color >= 0) + { + vp_text->drawmode |= (STYLE_COLORED|list->title_color);} +#endif + display->puts_scroll_style_offset(0, 0, list->title, + vp_text->drawmode, 0); + return true; +} + +void list_draw(struct screen *display, struct viewport *parent, + struct gui_synclist *list) +{ + int start, end, line_height, i; + int icon_width = get_icon_width(display->screen_type) + ICON_PADDING; + bool show_cursor = !global_settings.cursor_style && + list->show_selection_marker; +#ifdef HAVE_LCD_COLOR + unsigned char cur_line = 0; +#endif + int item_offset; + bool show_title; + line_height = font_get(parent->font)->height; + display->set_viewport(parent); + display->clear_viewport(); + display->stop_scroll(); + list_text[display->screen_type] = *parent; + if ((show_title = draw_title(display, parent, list))) + { + list_text[display->screen_type].y += list_title_height(list, parent); + list_text[display->screen_type].height -= list_title_height(list, parent); + } + + start = list->start_item[display->screen_type]; + end = start + viewport_get_nb_lines(&list_text[display->screen_type]); + + /* draw the scrollbar if its needed */ + if (global_settings.scrollbar && + viewport_get_nb_lines(&list_text[display->screen_type]) < list->nb_items) + { + struct viewport vp; + vp = list_text[display->screen_type]; + vp.width = SCROLLBAR_WIDTH; + list_text[display->screen_type].width -= SCROLLBAR_WIDTH; + list_text[display->screen_type].x += SCROLLBAR_WIDTH; + vp.height = line_height * + viewport_get_nb_lines(&list_text[display->screen_type]); + vp.x = parent->x; + display->set_viewport(&vp); + gui_scrollbar_draw(display, 0, 0, SCROLLBAR_WIDTH-1, + vp.height, list->nb_items, + list->start_item[display->screen_type], + list->start_item[display->screen_type] + end-start, + VERTICAL); + } + else if (show_title) + { + /* shift everything right a bit... */ + list_text[display->screen_type].width -= SCROLLBAR_WIDTH; + list_text[display->screen_type].x += SCROLLBAR_WIDTH; + } + + /* setup icon placement */ + list_icons[display->screen_type] = list_text[display->screen_type]; + int icon_count = global_settings.show_icons && + (list->callback_get_item_icon != NULL) ? 1 : 0; + if (show_cursor) + icon_count++; + if (icon_count) + { + list_icons[display->screen_type].width = icon_width * icon_count; + list_text[display->screen_type].width -= + list_icons[display->screen_type].width + ICON_PADDING; + list_text[display->screen_type].x += + list_icons[display->screen_type].width + ICON_PADDING; + } + + for (i=start; inb_items; i++) + { + /* do the text */ + unsigned char *s; + char entry_buffer[MAX_PATH]; + unsigned char *entry_name; + int text_pos = 0; + s = list->callback_get_item_name(i, list->data, entry_buffer); + entry_name = P2STR(s); + display->set_viewport(&list_text[display->screen_type]); + list_text[display->screen_type].drawmode = 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(list, item_width, + text_pos, display, + &list_text[display->screen_type]); + +#ifdef HAVE_LCD_COLOR + /* if the list has a color callback */ + if (list->callback_get_item_color) + { + int color = list->callback_get_item_color(i, list->data); + /* if color selected */ + if (color >= 0) + { + list_text[display->screen_type].drawmode |= STYLE_COLORED|color; + } + } +#endif + + if(list->show_selection_marker && global_settings.cursor_style && + i >= list->selected_item && + i < list->selected_item + list->selected_size) + {/* The selected item must be displayed scrolling */ + if (global_settings.cursor_style == 1 || display->depth < 16) + { + /* Display inverted-line-style */ + list_text[display->screen_type].drawmode |= STYLE_INVERT; + } +#ifdef HAVE_LCD_COLOR + else if (global_settings.cursor_style == 2) + { + /* Display colour line selector */ + list_text[display->screen_type].drawmode |= STYLE_COLORBAR; + } + else if (global_settings.cursor_style == 3) + { + /* Display gradient line selector */ + list_text[display->screen_type].drawmode = STYLE_GRADIENT; + + /* Make the lcd driver know how many lines the gradient should + cover and current line number */ + /* number of selected lines */ + list_text[display->screen_type].drawmode |= NUMLN_PACK(list->selected_size); + /* current line number, zero based */ + list_text[display->screen_type].drawmode |= CURLN_PACK(cur_line); + cur_line++; + } +#endif + /* if the text is smaller than the viewport size */ + 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); + } + else + { + display->puts_scroll_style_offset(0, i-start, entry_name, + list_text[display->screen_type].drawmode, item_offset); + } + } + else + display->puts_style_offset(0, i-start, entry_name, + list_text[display->screen_type].drawmode, item_offset); + /* do the icon */ + if (list->callback_get_item_icon && global_settings.show_icons) + { + display->set_viewport(&list_icons[display->screen_type]); + screen_put_icon_with_offset(display, show_cursor?1:0, + (i-start),show_cursor?ICON_PADDING:0,0, + list->callback_get_item_icon(i, list->data)); + if (show_cursor && i >= list->selected_item && + i < list->selected_item + list->selected_size) + { + screen_put_icon(display, 0, i-start, Icon_Cursor); + } + } + else if (show_cursor && i >= list->selected_item && + i < list->selected_item + list->selected_size) + { + display->set_viewport(&list_icons[display->screen_type]); + screen_put_icon(display, 0, (i-start), Icon_Cursor); + } + } + + display->set_viewport(parent); + display->update_viewport(); + display->set_viewport(NULL); +} + + diff --git a/apps/gui/charcell/list.c b/apps/gui/charcell/list.c new file mode 100644 index 0000000000..3d699e84dd --- /dev/null +++ b/apps/gui/charcell/list.c @@ -0,0 +1,129 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* This file contains the code to draw the list widget on BITMAP LCDs. */ + +#include "config.h" +#include "lcd.h" +#include "font.h" +#include "button.h" +#include "sprintf.h" +#include "string.h" +#include "settings.h" +#include "kernel.h" +#include "system.h" + +#include "list.h" +#include "screen_access.h" +#include "scrollbar.h" +#include "statusbar.h" +#include "textarea.h" +#include "lang.h" +#include "sound.h" +#include "misc.h" +#include "talk.h" + +void list_draw(struct screen *display, struct viewport *parent, + struct gui_synclist *gui_list) +{ + (void)parent; + int text_pos; + bool draw_icons = (gui_list->callback_get_item_icon != NULL && + global_settings.show_icons); + bool draw_cursor; + int i; + int lines; + int start, end; + + display->set_viewport(NULL); + lines = display->nb_lines; + + 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]; + + gui_list->last_displayed_selected_item = gui_list->selected_item; + + /* Adjust the position of icon, cursor, text for the list */ + draw_cursor = true; + if(draw_icons) + text_pos = 2; /* here it's in chars */ + else + text_pos = 1; + + 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] + 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); + + + 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 */ + display->puts_scroll(text_pos, i, entry_name); + + 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) + { + display->puts_scroll(text_pos, i, entry_name); + } + else + { + display->puts(text_pos, i, entry_name); + } + } + /* 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) + { + screen_put_icon(display, 1, i, icon); + } + } + } + + display->update_viewport(); + gui_textarea_update(display); +} diff --git a/apps/gui/list.c b/apps/gui/list.c index bc21976449..fbc417edee 100644 --- a/apps/gui/list.c +++ b/apps/gui/list.c @@ -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,11 +57,46 @@ static bool offset_out_of_view = false; #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); + } +} +#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 @@ -82,7 +118,7 @@ void gui_synclist_init(struct gui_synclist * gui_list, 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 +127,7 @@ void gui_synclist_init(struct gui_synclist * gui_list, #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 +155,10 @@ void gui_synclist_hide_selection_marker(struct gui_synclist * lists, bool hide) #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 +169,7 @@ static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_wid 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 +177,8 @@ static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_wid { /* 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 +187,32 @@ static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_wid 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]; +#ifdef HAVE_LCD_BITMAP + 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 +306,12 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list, 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]; +#ifdef HAVE_LCD_BITMAP + 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 +350,12 @@ void gui_synclist_add_item(struct gui_synclist * gui_list) */ 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 +430,14 @@ void gui_synclist_set_voice_callback(struct gui_synclist * lists, 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) { diff --git a/apps/gui/list.h b/apps/gui/list.h index 3bd3d25c49..48dd736d00 100644 --- a/apps/gui/list.h +++ b/apps/gui/list.h @@ -123,58 +123,9 @@ struct gui_synclist 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 */ @@ -183,17 +134,8 @@ extern void gui_list_screen_scroll_step(int ofs); /* 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_init( 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); diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c new file mode 100644 index 0000000000..c59a1d9ca2 --- /dev/null +++ b/apps/gui/viewport.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "lcd.h" +#include "font.h" +#include "sprintf.h" +#include "string.h" +#include "settings.h" +#include "kernel.h" +#include "system.h" +#include "misc.h" +#include "atoi.h" +#include "viewport.h" +#include "statusbar.h" +#include "screen_access.h" + +int viewport_get_nb_lines(struct viewport *vp) +{ +#ifdef HAVE_LCD_BITMAP + return vp->height/font_get(vp->font)->height; +#else + (void)vp; + return 2; +#endif +} + + +void viewport_set_defaults(struct viewport *vp, enum screen_type screen) +{ + vp->x = 0; + vp->width = screens[screen].width; + + vp->y = global_settings.statusbar?STATUSBAR_HEIGHT:0; + vp->height = screens[screen].height - vp->y +#ifdef HAS_BUTTONBAR + - screens[screen].has_buttonbar?BUTTONBAR_HEIGHT:0 +#endif + ; +#ifdef HAVE_LCD_BITMAP + vp->drawmode = DRMODE_SOLID; + vp->font = FONT_UI; /* default to UI to discourage SYSFONT use */ +#endif + if (screens[screen].depth > 1) + { +#ifdef HAVE_LCD_COLOR + vp->fg_pattern = global_settings.fg_color; + vp->bg_pattern = global_settings.bg_color; + vp->lss_pattern = global_settings.lss_color; + vp->lse_pattern = global_settings.lse_color; + vp->lst_pattern = global_settings.lst_color; +#elif LCD_DEPTH > 1 + vp->fg_pattern = LCD_DEFAULT_FG; + vp->bg_pattern = LCD_DEFAULT_BG; +#endif + } +} diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h new file mode 100644 index 0000000000..93059a4069 --- /dev/null +++ b/apps/gui/viewport.h @@ -0,0 +1,43 @@ + +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "lcd.h" +#include "font.h" +#include "sprintf.h" +#include "string.h" +#include "settings.h" +#include "kernel.h" +#include "system.h" +#include "misc.h" +#include "screen_access.h" + +/* return the number of text lines in the vp viewport */ +int viewport_get_nb_lines(struct viewport *vp); + +#define VP_ERROR 0 +#define VP_DIMENSIONS 0x1 +#define VP_COLORS 0x2 +#define VP_SELECTIONCOLORS 0x4 +/* load a viewport struct from a config string. + returns a combination of the above to say which were loaded ok from the string */ +int viewport_load_config(const char *config, struct viewport *vp); + +void viewport_set_defaults(struct viewport *vp, enum screen_type screen); diff --git a/apps/main.c b/apps/main.c index 3b2d516bde..bb29eb73dc 100644 --- a/apps/main.c +++ b/apps/main.c @@ -125,7 +125,13 @@ void app_main(void) 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(); } diff --git a/apps/menus/display_menu.c b/apps/menus/display_menu.c index a68defdfd4..c8d39c7395 100644 --- a/apps/menus/display_menu.c +++ b/apps/menus/display_menu.c @@ -297,8 +297,20 @@ MAKE_MENU(scroll_settings_menu, ID2P(LANG_SCROLL_MENU), 0, Icon_NOICON, /***********************************/ /* 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 diff --git a/apps/settings.c b/apps/settings.c index 4ac646a84c..3cf5de58ac 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -951,7 +951,7 @@ void settings_apply(void) if (global_settings.colors_file[0]) read_color_theme_file(); #endif - + list_init_viewports(); } diff --git a/apps/tree.c b/apps/tree.c index 0b4ea95c41..ec70cb3e2e 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -311,8 +311,7 @@ void tree_gui_init(void) 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 }