summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/FILES2
-rw-r--r--apps/SOURCES6
-rw-r--r--apps/gui/bitmap/list.c276
-rw-r--r--apps/gui/charcell/list.c129
-rw-r--r--apps/gui/list.c413
-rw-r--r--apps/gui/list.h65
-rw-r--r--apps/gui/viewport.c73
-rw-r--r--apps/gui/viewport.h43
-rw-r--r--apps/main.c6
-rw-r--r--apps/menus/display_menu.c14
-rw-r--r--apps/settings.c2
-rw-r--r--apps/tree.c3
12 files changed, 627 insertions, 405 deletions
diff --git a/apps/FILES b/apps/FILES
index d08114d..e465701 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 e27e15d..0d23f42 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 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 @@ 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 3bd3d25..48dd736 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 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 @@ 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 a68defd..c8d39c7 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 4ac646a..3cf5de5 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 0b4ea95..ec70cb3 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
}