FS#8457 - convert the list drawing code to use viewports. This does not include any of the customizability which was in the patch, so unless any bugs show up users should not notice any difference.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16527 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/FILES b/apps/FILES
index d08114d..e465701 100644
--- a/apps/FILES
+++ b/apps/FILES
@@ -40,6 +40,8 @@
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 e27e15d..0d23f42 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -54,6 +54,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
@@ -63,6 +68,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
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
new file mode 100644
index 0000000..63f24dd
--- /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; i<end && i<list->nb_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 0000000..3d699e8
--- /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 bc21976..fbc417e 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 @@
#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 @@
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 @@
#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 @@
#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 @@
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 @@
{
/* 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 @@
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 @@
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_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 @@
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 3bd3d25..48dd736 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -123,58 +123,9 @@
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 @@
/* 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);
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
new file mode 100644
index 0000000..c59a1d9
--- /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 0000000..93059a4
--- /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 3b2d516..bb29eb7 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -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();
}
diff --git a/apps/menus/display_menu.c b/apps/menus/display_menu.c
index a68defd..c8d39c7 100644
--- a/apps/menus/display_menu.c
+++ b/apps/menus/display_menu.c
@@ -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
diff --git a/apps/settings.c b/apps/settings.c
index 4ac646a..3cf5de5 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -951,7 +951,7 @@
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 0b4ea95..ec70cb3 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -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
}