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 d08114dc3a..e4657013c5 100644
--- a/apps/FILES
+++ b/apps/FILES
@@ -40,6 +40,8 @@ codecs/spc/SOURCES
40codecs/Tremor/* 40codecs/Tremor/*
41eqs/*.cfg 41eqs/*.cfg
42gui/*.[ch] 42gui/*.[ch]
43gui/charcell/*.[ch]
44gui/bitmap/*.[ch]
43keymaps/*.[ch] 45keymaps/*.[ch]
44lang/SOURCES 46lang/SOURCES
45lang/*.lang 47lang/*.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
54gui/icon.c 54gui/icon.c
55#endif 55#endif
56gui/list.c 56gui/list.c
57#ifdef HAVE_LCD_BITMAP
58gui/bitmap/list.c
59#else
60gui/charcell/list.c
61#endif
57gui/option_select.c 62gui/option_select.c
58gui/quickscreen.c 63gui/quickscreen.c
59gui/scrollbar.c 64gui/scrollbar.c
@@ -63,6 +68,7 @@ gui/textarea.c
63gui/yesno.c 68gui/yesno.c
64gui/wps_debug.c 69gui/wps_debug.c
65gui/wps_parser.c 70gui/wps_parser.c
71gui/viewport.c
66 72
67#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) 73#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
68gui/backdrop.c 74gui/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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jonathan Gordon
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20/* This file contains the code to draw the list widget on BITMAP LCDs. */
21
22#include "config.h"
23#include "lcd.h"
24#include "font.h"
25#include "button.h"
26#include "sprintf.h"
27#include "string.h"
28#include "settings.h"
29#include "kernel.h"
30#include "system.h"
31
32#include "action.h"
33#include "screen_access.h"
34#include "list.h"
35#include "scrollbar.h"
36#include "statusbar.h"
37#include "textarea.h"
38#include "lang.h"
39#include "sound.h"
40#include "misc.h"
41#include "talk.h"
42#include "viewport.h"
43
44#define SCROLLBAR_WIDTH 6
45#define ICON_PADDING 1
46
47/* globals */
48struct viewport title_text[NB_SCREENS], title_icons[NB_SCREENS],
49 list_text[NB_SCREENS], list_icons[NB_SCREENS];
50
51/* should probably be moved somewhere else */
52int list_title_height(struct gui_synclist *list, struct viewport *vp)
53{
54 (void)list;
55 return font_get(vp->font)->height;
56}
57int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width,
58 int text_pos, struct screen * display,
59 struct viewport *vp);
60bool list_display_title(struct gui_synclist *list, struct viewport *vp);
61
62/* Draw the list...
63 internal screen layout:
64 -----------------
65 |TI| title | TI is title icon
66 -----------------
67 | | | |
68 |S|I| | S - scrollbar
69 | | | items | I - icons
70 | | | |
71 ------------------
72*/
73static bool draw_title(struct screen *display, struct viewport *parent,
74 struct gui_synclist *list)
75{
76 struct viewport *vp_icons = &title_icons[display->screen_type];
77 struct viewport *vp_text = &title_text[display->screen_type];
78 if (!list_display_title(list, parent))
79 return false;
80 *vp_text = *parent;
81 vp_text->height = list_title_height(list, parent);
82 if (list->title_icon != Icon_NOICON && global_settings.show_icons)
83 {
84 *vp_icons = *vp_text;
85 vp_icons->width = get_icon_width(display->screen_type)
86 + ICON_PADDING*2;
87 vp_icons->x += ICON_PADDING;
88
89 vp_text->width -= vp_icons->width + vp_icons->x;
90 vp_text->x += vp_icons->width + vp_icons->x;
91
92 display->set_viewport(vp_icons);
93 screen_put_icon(display, 0, 0, list->title_icon);
94 }
95 display->set_viewport(vp_text);
96 vp_text->drawmode = STYLE_DEFAULT;
97#ifdef HAVE_LCD_COLOR
98 if (list->title_color >= 0)
99 {
100 vp_text->drawmode |= (STYLE_COLORED|list->title_color);}
101#endif
102 display->puts_scroll_style_offset(0, 0, list->title,
103 vp_text->drawmode, 0);
104 return true;
105}
106
107void list_draw(struct screen *display, struct viewport *parent,
108 struct gui_synclist *list)
109{
110 int start, end, line_height, i;
111 int icon_width = get_icon_width(display->screen_type) + ICON_PADDING;
112 bool show_cursor = !global_settings.cursor_style &&
113 list->show_selection_marker;
114#ifdef HAVE_LCD_COLOR
115 unsigned char cur_line = 0;
116#endif
117 int item_offset;
118 bool show_title;
119 line_height = font_get(parent->font)->height;
120 display->set_viewport(parent);
121 display->clear_viewport();
122 display->stop_scroll();
123 list_text[display->screen_type] = *parent;
124 if ((show_title = draw_title(display, parent, list)))
125 {
126 list_text[display->screen_type].y += list_title_height(list, parent);
127 list_text[display->screen_type].height -= list_title_height(list, parent);
128 }
129
130 start = list->start_item[display->screen_type];
131 end = start + viewport_get_nb_lines(&list_text[display->screen_type]);
132
133 /* draw the scrollbar if its needed */
134 if (global_settings.scrollbar &&
135 viewport_get_nb_lines(&list_text[display->screen_type]) < list->nb_items)
136 {
137 struct viewport vp;
138 vp = list_text[display->screen_type];
139 vp.width = SCROLLBAR_WIDTH;
140 list_text[display->screen_type].width -= SCROLLBAR_WIDTH;
141 list_text[display->screen_type].x += SCROLLBAR_WIDTH;
142 vp.height = line_height *
143 viewport_get_nb_lines(&list_text[display->screen_type]);
144 vp.x = parent->x;
145 display->set_viewport(&vp);
146 gui_scrollbar_draw(display, 0, 0, SCROLLBAR_WIDTH-1,
147 vp.height, list->nb_items,
148 list->start_item[display->screen_type],
149 list->start_item[display->screen_type] + end-start,
150 VERTICAL);
151 }
152 else if (show_title)
153 {
154 /* shift everything right a bit... */
155 list_text[display->screen_type].width -= SCROLLBAR_WIDTH;
156 list_text[display->screen_type].x += SCROLLBAR_WIDTH;
157 }
158
159 /* setup icon placement */
160 list_icons[display->screen_type] = list_text[display->screen_type];
161 int icon_count = global_settings.show_icons &&
162 (list->callback_get_item_icon != NULL) ? 1 : 0;
163 if (show_cursor)
164 icon_count++;
165 if (icon_count)
166 {
167 list_icons[display->screen_type].width = icon_width * icon_count;
168 list_text[display->screen_type].width -=
169 list_icons[display->screen_type].width + ICON_PADDING;
170 list_text[display->screen_type].x +=
171 list_icons[display->screen_type].width + ICON_PADDING;
172 }
173
174 for (i=start; i<end && i<list->nb_items; i++)
175 {
176 /* do the text */
177 unsigned char *s;
178 char entry_buffer[MAX_PATH];
179 unsigned char *entry_name;
180 int text_pos = 0;
181 s = list->callback_get_item_name(i, list->data, entry_buffer);
182 entry_name = P2STR(s);
183 display->set_viewport(&list_text[display->screen_type]);
184 list_text[display->screen_type].drawmode = STYLE_DEFAULT;
185 /* position the string at the correct offset place */
186 int item_width,h;
187 display->getstringsize(entry_name, &item_width, &h);
188 item_offset = gui_list_get_item_offset(list, item_width,
189 text_pos, display,
190 &list_text[display->screen_type]);
191
192#ifdef HAVE_LCD_COLOR
193 /* if the list has a color callback */
194 if (list->callback_get_item_color)
195 {
196 int color = list->callback_get_item_color(i, list->data);
197 /* if color selected */
198 if (color >= 0)
199 {
200 list_text[display->screen_type].drawmode |= STYLE_COLORED|color;
201 }
202 }
203#endif
204
205 if(list->show_selection_marker && global_settings.cursor_style &&
206 i >= list->selected_item &&
207 i < list->selected_item + list->selected_size)
208 {/* The selected item must be displayed scrolling */
209 if (global_settings.cursor_style == 1 || display->depth < 16)
210 {
211 /* Display inverted-line-style */
212 list_text[display->screen_type].drawmode |= STYLE_INVERT;
213 }
214#ifdef HAVE_LCD_COLOR
215 else if (global_settings.cursor_style == 2)
216 {
217 /* Display colour line selector */
218 list_text[display->screen_type].drawmode |= STYLE_COLORBAR;
219 }
220 else if (global_settings.cursor_style == 3)
221 {
222 /* Display gradient line selector */
223 list_text[display->screen_type].drawmode = STYLE_GRADIENT;
224
225 /* Make the lcd driver know how many lines the gradient should
226 cover and current line number */
227 /* number of selected lines */
228 list_text[display->screen_type].drawmode |= NUMLN_PACK(list->selected_size);
229 /* current line number, zero based */
230 list_text[display->screen_type].drawmode |= CURLN_PACK(cur_line);
231 cur_line++;
232 }
233#endif
234 /* if the text is smaller than the viewport size */
235 if (item_offset > item_width - (list_text[display->screen_type].width - text_pos))
236 {
237 /* don't scroll */
238 display->puts_style_offset(0, i-start, entry_name,
239 list_text[display->screen_type].drawmode, item_offset);
240 }
241 else
242 {
243 display->puts_scroll_style_offset(0, i-start, entry_name,
244 list_text[display->screen_type].drawmode, item_offset);
245 }
246 }
247 else
248 display->puts_style_offset(0, i-start, entry_name,
249 list_text[display->screen_type].drawmode, item_offset);
250 /* do the icon */
251 if (list->callback_get_item_icon && global_settings.show_icons)
252 {
253 display->set_viewport(&list_icons[display->screen_type]);
254 screen_put_icon_with_offset(display, show_cursor?1:0,
255 (i-start),show_cursor?ICON_PADDING:0,0,
256 list->callback_get_item_icon(i, list->data));
257 if (show_cursor && i >= list->selected_item &&
258 i < list->selected_item + list->selected_size)
259 {
260 screen_put_icon(display, 0, i-start, Icon_Cursor);
261 }
262 }
263 else if (show_cursor && i >= list->selected_item &&
264 i < list->selected_item + list->selected_size)
265 {
266 display->set_viewport(&list_icons[display->screen_type]);
267 screen_put_icon(display, 0, (i-start), Icon_Cursor);
268 }
269 }
270
271 display->set_viewport(parent);
272 display->update_viewport();
273 display->set_viewport(NULL);
274}
275
276
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jonathan Gordon
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20/* This file contains the code to draw the list widget on BITMAP LCDs. */
21
22#include "config.h"
23#include "lcd.h"
24#include "font.h"
25#include "button.h"
26#include "sprintf.h"
27#include "string.h"
28#include "settings.h"
29#include "kernel.h"
30#include "system.h"
31
32#include "list.h"
33#include "screen_access.h"
34#include "scrollbar.h"
35#include "statusbar.h"
36#include "textarea.h"
37#include "lang.h"
38#include "sound.h"
39#include "misc.h"
40#include "talk.h"
41
42void list_draw(struct screen *display, struct viewport *parent,
43 struct gui_synclist *gui_list)
44{
45 (void)parent;
46 int text_pos;
47 bool draw_icons = (gui_list->callback_get_item_icon != NULL &&
48 global_settings.show_icons);
49 bool draw_cursor;
50 int i;
51 int lines;
52 int start, end;
53
54 display->set_viewport(NULL);
55 lines = display->nb_lines;
56
57 gui_textarea_clear(display);
58 start = 0;
59 end = display->nb_lines;
60 gui_list->last_displayed_start_item[display->screen_type] =
61 gui_list->start_item[display->screen_type];
62
63 gui_list->last_displayed_selected_item = gui_list->selected_item;
64
65 /* Adjust the position of icon, cursor, text for the list */
66 draw_cursor = true;
67 if(draw_icons)
68 text_pos = 2; /* here it's in chars */
69 else
70 text_pos = 1;
71
72 for (i = start; i < end; i++)
73 {
74 unsigned char *s;
75 char entry_buffer[MAX_PATH];
76 unsigned char *entry_name;
77 int current_item = gui_list->start_item[display->screen_type] + i;
78
79 /* When there are less items to display than the
80 * current available space on the screen, we stop*/
81 if(current_item >= gui_list->nb_items)
82 break;
83 s = gui_list->callback_get_item_name(current_item,
84 gui_list->data,
85 entry_buffer);
86 entry_name = P2STR(s);
87
88
89 if(gui_list->show_selection_marker &&
90 current_item >= gui_list->selected_item &&
91 current_item < gui_list->selected_item + gui_list->selected_size)
92 {/* The selected item must be displayed scrolling */
93 display->puts_scroll(text_pos, i, entry_name);
94
95 if (draw_cursor)
96 {
97 screen_put_icon_with_offset(display, 0, i,
98 (draw_scrollbar || SHOW_LIST_TITLE)?
99 SCROLLBAR_WIDTH: 0,
100 0, Icon_Cursor);
101 }
102 }
103 else
104 {/* normal item */
105 if(gui_list->scroll_all)
106 {
107 display->puts_scroll(text_pos, i, entry_name);
108 }
109 else
110 {
111 display->puts(text_pos, i, entry_name);
112 }
113 }
114 /* Icons display */
115 if(draw_icons)
116 {
117 enum themable_icons icon;
118 icon = gui_list->callback_get_item_icon(current_item,
119 gui_list->data);
120 if(icon > Icon_NOICON)
121 {
122 screen_put_icon(display, 1, i, icon);
123 }
124 }
125 }
126
127 display->update_viewport();
128 gui_textarea_update(display);
129}
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 @@
37#include "sound.h" 37#include "sound.h"
38#include "misc.h" 38#include "misc.h"
39#include "talk.h" 39#include "talk.h"
40#include "viewport.h"
40 41
41#ifdef HAVE_LCD_CHARCELLS 42#ifdef HAVE_LCD_CHARCELLS
42#define SCROLL_LIMIT 1 43#define SCROLL_LIMIT 1
@@ -56,11 +57,46 @@ static bool offset_out_of_view = false;
56#endif 57#endif
57static struct gui_synclist* last_list_displayed; 58static struct gui_synclist* last_list_displayed;
58 59
59#define SHOW_LIST_TITLE ((gui_list->title != NULL) && \
60 (display->nb_lines > 2))
61
62static void gui_list_select_at_offset(struct gui_synclist * gui_list, 60static void gui_list_select_at_offset(struct gui_synclist * gui_list,
63 int offset); 61 int offset);
62void list_draw(struct screen *display, struct viewport *parent, struct gui_synclist *list);
63
64#ifdef HAVE_LCD_BITMAP
65static struct viewport parent[NB_SCREENS];
66void list_init_viewports(void)
67{
68 int i;
69 struct viewport *vp;
70 FOR_NB_SCREENS(i)
71 {
72 vp = &parent[i];
73 viewport_set_defaults(vp, i);
74 }
75}
76#else
77static struct viewport parent[NB_SCREENS] =
78{
79 [SCREEN_MAIN] =
80 {
81 .x = 0,
82 .y = 0,
83 .width = LCD_WIDTH,
84 .height = LCD_HEIGHT
85 },
86};
87void list_init_viewports(void)
88{
89}
90#endif
91
92#ifdef HAVE_LCD_BITMAP
93bool list_display_title(struct gui_synclist *list, struct viewport *vp)
94{
95 return list->title != NULL && viewport_get_nb_lines(vp)>2;
96}
97#else
98#define list_display_title(l,v) false
99#endif
64 100
65/* 101/*
66 * Initializes a scrolling list 102 * Initializes a scrolling list
@@ -82,7 +118,7 @@ void gui_synclist_init(struct gui_synclist * gui_list,
82 gui_list->callback_get_item_icon = NULL; 118 gui_list->callback_get_item_icon = NULL;
83 gui_list->callback_get_item_name = callback_get_item_name; 119 gui_list->callback_get_item_name = callback_get_item_name;
84 gui_list->callback_speak_item = NULL; 120 gui_list->callback_speak_item = NULL;
85 gui_list_set_nb_items(gui_list, 0); 121 gui_list->nb_items = 0;
86 gui_list->selected_item = 0; 122 gui_list->selected_item = 0;
87 FOR_NB_SCREENS(i) 123 FOR_NB_SCREENS(i)
88 { 124 {
@@ -91,6 +127,7 @@ void gui_synclist_init(struct gui_synclist * gui_list,
91#ifdef HAVE_LCD_BITMAP 127#ifdef HAVE_LCD_BITMAP
92 gui_list->offset_position[i] = 0; 128 gui_list->offset_position[i] = 0;
93#endif 129#endif
130 gui_list->parent[i] = &parent[i];
94 } 131 }
95 gui_list->limit_scroll = false; 132 gui_list->limit_scroll = false;
96 gui_list->data=data; 133 gui_list->data=data;
@@ -118,8 +155,10 @@ void gui_synclist_hide_selection_marker(struct gui_synclist * lists, bool hide)
118 155
119 156
120#ifdef HAVE_LCD_BITMAP 157#ifdef HAVE_LCD_BITMAP
121static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width, 158int list_title_height(struct gui_synclist *list, struct viewport *vp);
122 int text_pos, struct screen * display) 159
160int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width,
161 int text_pos, struct screen * display, struct viewport *vp)
123{ 162{
124 int item_offset; 163 int item_offset;
125 164
@@ -130,7 +169,7 @@ static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_wid
130 else 169 else
131 { 170 {
132 /* if text is smaller then view */ 171 /* if text is smaller then view */
133 if (item_width <= display->width - text_pos) 172 if (item_width <= vp->width - text_pos)
134 { 173 {
135 item_offset = 0; 174 item_offset = 0;
136 } 175 }
@@ -138,8 +177,8 @@ static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_wid
138 { 177 {
139 /* if text got out of view */ 178 /* if text got out of view */
140 if (gui_list->offset_position[display->screen_type] > 179 if (gui_list->offset_position[display->screen_type] >
141 item_width - (display->width - text_pos)) 180 item_width - (vp->width - text_pos))
142 item_offset = item_width - (display->width - text_pos); 181 item_offset = item_width - (vp->width - text_pos);
143 else 182 else
144 item_offset = gui_list->offset_position[display->screen_type]; 183 item_offset = gui_list->offset_position[display->screen_type];
145 } 184 }
@@ -148,341 +187,32 @@ static int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_wid
148 return item_offset; 187 return item_offset;
149} 188}
150#endif 189#endif
151
152/*
153 * Draws the list on the attached screen
154 * - gui_list : the list structure
155 */
156static void gui_list_draw_smart(struct gui_synclist *gui_list, struct screen * display)
157{
158 int text_pos;
159 bool draw_icons = (gui_list->callback_get_item_icon != NULL && global_settings.show_icons);
160 bool draw_cursor;
161 int i;
162 int lines;
163 static int last_lines[NB_SCREENS] = {0};
164#ifdef HAVE_LCD_BITMAP
165 int item_offset;
166 int old_margin = display->getxmargin();
167#endif
168 int start, end;
169 bool partial_draw = false;
170
171#ifdef HAVE_LCD_BITMAP
172 display->setfont(FONT_UI);
173 gui_textarea_update_nblines(display);
174#endif
175 /* Speed up UI by drawing the changed contents only. */
176 if (gui_list == last_list_displayed
177 && gui_list->last_displayed_start_item[display->screen_type] == gui_list->start_item[display->screen_type]
178 && gui_list->selected_size == 1)
179 {
180 partial_draw = true;
181 }
182
183 lines = display->nb_lines - SHOW_LIST_TITLE;
184 if (last_lines[display->screen_type] != lines)
185 {
186 gui_list_select_at_offset(gui_list, 0);
187 last_lines[display->screen_type] = lines;
188 }
189
190 if (partial_draw)
191 {
192 end = gui_list->last_displayed_selected_item - gui_list->start_item[display->screen_type];
193 i = gui_list->selected_item - gui_list->start_item[display->screen_type];
194 if (i < end )
195 {
196 start = i;
197 end++;
198 }
199 else
200 {
201 start = end;
202 end = i + 1;
203 }
204 }
205 else
206 {
207 gui_textarea_clear(display);
208 start = 0;
209 end = display->nb_lines;
210 gui_list->last_displayed_start_item[display->screen_type] = gui_list->start_item[display->screen_type];
211 last_list_displayed = gui_list;
212 }
213
214 gui_list->last_displayed_selected_item = gui_list->selected_item;
215
216 /* position and draw the list title & icon */
217 if (SHOW_LIST_TITLE && !partial_draw)
218 {
219 if (gui_list->title_icon != NOICON && draw_icons)
220 {
221 screen_put_icon(display, 0, 0, gui_list->title_icon);
222#ifdef HAVE_LCD_BITMAP
223 text_pos = get_icon_width(display->screen_type)+2; /* pixels */
224#else
225 text_pos = 1; /* chars */
226#endif
227 }
228 else
229 {
230 text_pos = 0;
231 }
232
233#ifdef HAVE_LCD_BITMAP
234 int title_style = STYLE_DEFAULT;
235#ifdef HAVE_LCD_COLOR
236 if (gui_list->title_color >= 0)
237 {
238 title_style |= STYLE_COLORED;
239 title_style |= gui_list->title_color;
240 }
241#endif
242 screen_set_xmargin(display, text_pos); /* margin for title */
243 item_offset = gui_list_get_item_offset(gui_list, gui_list->title_width,
244 text_pos, display);
245 if (item_offset > gui_list->title_width - (display->width - text_pos))
246 display->puts_style_offset(0, 0, gui_list->title,
247 title_style, item_offset);
248 else
249 display->puts_scroll_style_offset(0, 0, gui_list->title,
250 title_style, item_offset);
251#else
252 display->puts_scroll(text_pos, 0, gui_list->title);
253#endif
254 }
255
256 /* Adjust the position of icon, cursor, text for the list */
257#ifdef HAVE_LCD_BITMAP
258 gui_textarea_update_nblines(display);
259 bool draw_scrollbar;
260
261 draw_scrollbar = (global_settings.scrollbar &&
262 lines < gui_list->nb_items);
263
264 draw_cursor = !global_settings.cursor_style &&
265 gui_list->show_selection_marker;
266 text_pos = 0; /* here it's in pixels */
267 if(draw_scrollbar || SHOW_LIST_TITLE) /* indent if there's
268 a title */
269 {
270 text_pos += SCROLLBAR_WIDTH;
271 }
272 if(draw_cursor)
273 text_pos += get_icon_width(display->screen_type) + 2;
274
275 if(draw_icons)
276 text_pos += get_icon_width(display->screen_type) + 2;
277#else
278 draw_cursor = true;
279 if(draw_icons)
280 text_pos = 2; /* here it's in chars */
281 else
282 text_pos = 1;
283#endif
284
285#ifdef HAVE_LCD_BITMAP
286 screen_set_xmargin(display, text_pos); /* margin for list */
287#endif
288
289 if (SHOW_LIST_TITLE)
290 {
291 start++;
292 if (end < display->nb_lines)
293 end++;
294 }
295
296#ifdef HAVE_LCD_COLOR
297 unsigned char cur_line = 0;
298#endif
299 for (i = start; i < end; i++)
300 {
301 unsigned char *s;
302 char entry_buffer[MAX_PATH];
303 unsigned char *entry_name;
304 int current_item = gui_list->start_item[display->screen_type] +
305 (SHOW_LIST_TITLE ? i-1 : i);
306
307 /* When there are less items to display than the
308 * current available space on the screen, we stop*/
309 if(current_item >= gui_list->nb_items)
310 break;
311 s = gui_list->callback_get_item_name(current_item,
312 gui_list->data,
313 entry_buffer);
314 entry_name = P2STR(s);
315
316#ifdef HAVE_LCD_BITMAP
317 int style = STYLE_DEFAULT;
318 /* position the string at the correct offset place */
319 int item_width,h;
320 display->getstringsize(entry_name, &item_width, &h);
321 item_offset = gui_list_get_item_offset(gui_list, item_width,
322 text_pos, display);
323#endif
324
325#ifdef HAVE_LCD_COLOR
326 /* if the list has a color callback */
327 if (gui_list->callback_get_item_color)
328 {
329 int color = gui_list->callback_get_item_color(current_item,
330 gui_list->data);
331 /* if color selected */
332 if (color >= 0)
333 {
334 style |= STYLE_COLORED;
335 style |= color;
336 }
337 }
338#endif
339
340 if(gui_list->show_selection_marker &&
341 current_item >= gui_list->selected_item &&
342 current_item < gui_list->selected_item + gui_list->selected_size)
343 {/* The selected item must be displayed scrolling */
344#ifdef HAVE_LCD_BITMAP
345 if (global_settings.cursor_style == 1
346#ifdef HAVE_REMOTE_LCD
347 || display->screen_type == SCREEN_REMOTE
348#endif
349 )
350 {
351 /* Display inverted-line-style */
352 style |= STYLE_INVERT;
353 }
354#ifdef HAVE_LCD_COLOR
355 else if (global_settings.cursor_style == 2)
356 {
357 /* Display colour line selector */
358 style |= STYLE_COLORBAR;
359 }
360 else if (global_settings.cursor_style == 3)
361 {
362 /* Display gradient line selector */
363 style = STYLE_GRADIENT;
364
365 /* Make the lcd driver know how many lines the gradient should
366 cover and current line number */
367 /* number of selected lines */
368 style |= NUMLN_PACK(gui_list->selected_size);
369 /* current line number, zero based */
370 style |= CURLN_PACK(cur_line);
371 cur_line++;
372 }
373#endif
374 else /* if (!global_settings.cursor_style) */
375 {
376 if (current_item % gui_list->selected_size != 0)
377 draw_cursor = false;
378 }
379 /* if the text is smaller than the viewport size */
380 if (item_offset > item_width - (display->width - text_pos))
381 {
382 /* don't scroll */
383 display->puts_style_offset(0, i, entry_name,
384 style, item_offset);
385 }
386 else
387 {
388 display->puts_scroll_style_offset(0, i, entry_name,
389 style, item_offset);
390 }
391#else
392 display->puts_scroll(text_pos, i, entry_name);
393#endif
394
395 if (draw_cursor)
396 {
397 screen_put_icon_with_offset(display, 0, i,
398 (draw_scrollbar || SHOW_LIST_TITLE)?
399 SCROLLBAR_WIDTH: 0,
400 0, Icon_Cursor);
401 }
402 }
403 else
404 {/* normal item */
405 if(gui_list->scroll_all)
406 {
407#ifdef HAVE_LCD_BITMAP
408 display->puts_scroll_style_offset(0, i, entry_name,
409 style, item_offset);
410#else
411 display->puts_scroll(text_pos, i, entry_name);
412#endif
413 }
414 else
415 {
416#ifdef HAVE_LCD_BITMAP
417 display->puts_style_offset(0, i, entry_name,
418 style, item_offset);
419#else
420 display->puts(text_pos, i, entry_name);
421#endif
422 }
423 }
424 /* Icons display */
425 if(draw_icons)
426 {
427 enum themable_icons icon;
428 icon = gui_list->callback_get_item_icon(current_item, gui_list->data);
429 if(icon > Icon_NOICON)
430 {
431#ifdef HAVE_LCD_BITMAP
432 int x = draw_cursor?1:0;
433 int x_off = (draw_scrollbar || SHOW_LIST_TITLE) ? SCROLLBAR_WIDTH: 0;
434 screen_put_icon_with_offset(display, x, i,
435 x_off, 0, icon);
436#else
437 screen_put_icon(display, 1, i, icon);
438#endif
439 }
440 }
441 }
442
443#ifdef HAVE_LCD_BITMAP
444 /* Draw the scrollbar if needed*/
445 if(draw_scrollbar)
446 {
447 int y_start = gui_textarea_get_ystart(display);
448 if (SHOW_LIST_TITLE)
449 y_start += display->char_height;
450 int scrollbar_y_end = display->char_height *
451 lines + y_start;
452 gui_scrollbar_draw(display, 0, y_start, SCROLLBAR_WIDTH-1,
453 scrollbar_y_end - y_start, gui_list->nb_items,
454 gui_list->start_item[display->screen_type],
455 gui_list->start_item[display->screen_type] + lines, VERTICAL);
456 }
457
458 screen_set_xmargin(display, old_margin);
459#endif
460
461 gui_textarea_update(display);
462}
463
464/* 190/*
465 * Force a full screen update. 191 * Force a full screen update.
466 */ 192 */
193
467void gui_synclist_draw(struct gui_synclist *gui_list) 194void gui_synclist_draw(struct gui_synclist *gui_list)
468{ 195{
469 int i; 196 int i;
470 FOR_NB_SCREENS(i) 197 FOR_NB_SCREENS(i)
471 { 198 {
472 last_list_displayed = NULL; 199 last_list_displayed = NULL;
473 gui_list_draw_smart(gui_list, &screens[i]); 200 list_draw(&screens[i], gui_list->parent[i], gui_list);
474 } 201 }
475} 202}
476 203
477
478
479/* sets up the list so the selection is shown correctly on the screen */ 204/* sets up the list so the selection is shown correctly on the screen */
480static void gui_list_put_selection_on_screen(struct gui_synclist * gui_list, 205static void gui_list_put_selection_on_screen(struct gui_synclist * gui_list,
481 enum screen_type screen) 206 enum screen_type screen)
482{ 207{
483 struct screen *display = &screens[screen]; 208 int nb_lines;
484 int nb_lines = display->nb_lines - SHOW_LIST_TITLE;
485 int difference = gui_list->selected_item - gui_list->start_item[screen]; 209 int difference = gui_list->selected_item - gui_list->start_item[screen];
210 struct viewport vp = *gui_list->parent[screen];
211#ifdef HAVE_LCD_BITMAP
212 if (list_display_title(gui_list, gui_list->parent[screen]))
213 vp.height -= list_title_height(gui_list,gui_list->parent[screen]);
214#endif
215 nb_lines = viewport_get_nb_lines(&vp);
486 216
487 /* edge case,, selected last item */ 217 /* edge case,, selected last item */
488 if (gui_list->selected_item == gui_list->nb_items -1) 218 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,
576 int i, nb_lines, screen_top; 306 int i, nb_lines, screen_top;
577 FOR_NB_SCREENS(i) 307 FOR_NB_SCREENS(i)
578 { 308 {
579 struct screen *display = &screens[i]; 309 struct viewport vp = *gui_list->parent[i];
580 nb_lines = display->nb_lines - SHOW_LIST_TITLE; 310#ifdef HAVE_LCD_BITMAP
311 if (list_display_title(gui_list, gui_list->parent[i]))
312 vp.height -= list_title_height(gui_list,gui_list->parent[i]);
313#endif
314 nb_lines = viewport_get_nb_lines(&vp);
581 if (offset > 0) 315 if (offset > 0)
582 { 316 {
583 screen_top = gui_list->nb_items-nb_lines; 317 screen_top = gui_list->nb_items-nb_lines;
@@ -616,23 +350,12 @@ void gui_synclist_add_item(struct gui_synclist * gui_list)
616 */ 350 */
617void gui_synclist_del_item(struct gui_synclist * gui_list) 351void gui_synclist_del_item(struct gui_synclist * gui_list)
618{ 352{
619 int i;
620 if(gui_list->nb_items > 0) 353 if(gui_list->nb_items > 0)
621 { 354 {
622 if (gui_list->selected_item == gui_list->nb_items-1) 355 if (gui_list->selected_item == gui_list->nb_items-1)
623 gui_list->selected_item--; 356 gui_list->selected_item--;
624 FOR_NB_SCREENS(i)
625 {
626 gui_textarea_update_nblines(&screens[i]);
627 int nb_lines = screens[i].nb_lines;
628 int dist_start_from_end = gui_list->nb_items
629 - gui_list->start_item[i] - 1;
630
631 /* scroll the list if needed */
632 if( (dist_start_from_end < nb_lines) && (gui_list->start_item[i] != 0) )
633 gui_list->start_item[i]--;
634 }
635 gui_list->nb_items--; 357 gui_list->nb_items--;
358 gui_synclist_select_item(gui_list, gui_list->selected_item);
636 } 359 }
637} 360}
638 361
@@ -707,6 +430,14 @@ void gui_synclist_set_voice_callback(struct gui_synclist * lists,
707 lists->callback_speak_item = voice_callback; 430 lists->callback_speak_item = voice_callback;
708} 431}
709 432
433#ifdef HAVE_LCD_COLOR
434void gui_synclist_set_color_callback(struct gui_synclist * lists,
435 list_get_color color_callback)
436{
437 lists->callback_get_item_color = color_callback;
438}
439#endif
440
710static void gui_synclist_select_next_page(struct gui_synclist * lists, 441static void gui_synclist_select_next_page(struct gui_synclist * lists,
711 enum screen_type screen) 442 enum screen_type screen)
712{ 443{
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
123 int title_color; 123 int title_color;
124 list_get_color *callback_get_item_color; 124 list_get_color *callback_get_item_color;
125#endif 125#endif
126 struct viewport *parent[NB_SCREENS];
126}; 127};
127 128
128/*
129 * Sets the numbers of items the list can currently display
130 * note that the list's context like the currently pointed item is resetted
131 * - gui_list : the list structure
132 * - nb_items : the numbers of items you want
133 */
134#define gui_list_set_nb_items(gui_list, nb) \
135 (gui_list)->nb_items = nb
136
137/*
138 * Returns the numbers of items currently in the list
139 * - gui_list : the list structure
140 */
141#define gui_list_get_nb_items(gui_list) \
142 (gui_list)->nb_items
143
144/*
145 * Sets the icon callback function
146 * - gui_list : the list structure
147 * - _callback : the callback function
148 */
149#define gui_list_set_icon_callback(gui_list, _callback) \
150 (gui_list)->callback_get_item_icon=_callback
151
152/*
153 * Sets the voice callback function
154 * - gui_list : the list structure
155 * - _callback : the callback function
156 */
157#define gui_list_set_voice_callback(gui_list, _callback) \
158 (gui_list)->callback_speak_item=_callback
159
160#ifdef HAVE_LCD_COLOR
161/*
162 * Sets the color callback function
163 * - gui_list : the list structure
164 * - _callback : the callback function
165 */
166#define gui_list_set_color_callback(gui_list, _callback) \
167 (gui_list)->callback_get_item_color=_callback
168#endif
169
170/*
171 * Gives the position of the selected item
172 * - gui_list : the list structure
173 * Returns the position
174 */
175#define gui_list_get_sel_pos(gui_list) \
176 (gui_list)->selected_item
177
178 129
179#ifdef HAVE_LCD_BITMAP 130#ifdef HAVE_LCD_BITMAP
180/* parse global setting to static int */ 131/* parse global setting to static int */
@@ -183,17 +134,8 @@ extern void gui_list_screen_scroll_step(int ofs);
183/* parse global setting to static bool */ 134/* parse global setting to static bool */
184extern void gui_list_screen_scroll_out_of_view(bool enable); 135extern void gui_list_screen_scroll_out_of_view(bool enable);
185#endif /* HAVE_LCD_BITMAP */ 136#endif /* HAVE_LCD_BITMAP */
186/*
187 * Tells the list wether it should stop when reaching the top/bottom
188 * or should continue (by going to bottom/top)
189 * - gui_list : the list structure
190 * - scroll :
191 * - true : stops when reaching top/bottom
192 * - false : continues to go to bottom/top when reaching top/bottom
193 */
194#define gui_list_limit_scroll(gui_list, scroll) \
195 (gui_list)->limit_scroll=scroll
196 137
138void list_init_viewports(void);
197 139
198extern void gui_synclist_init( 140extern void gui_synclist_init(
199 struct gui_synclist * lists, 141 struct gui_synclist * lists,
@@ -205,6 +147,9 @@ extern void gui_synclist_init(
205extern void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items); 147extern void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items);
206extern void gui_synclist_set_icon_callback(struct gui_synclist * lists, list_get_icon icon_callback); 148extern void gui_synclist_set_icon_callback(struct gui_synclist * lists, list_get_icon icon_callback);
207extern void gui_synclist_set_voice_callback(struct gui_synclist * lists, list_speak_item voice_callback); 149extern void gui_synclist_set_voice_callback(struct gui_synclist * lists, list_speak_item voice_callback);
150#ifdef HAVE_LCD_COLOR
151extern void gui_synclist_set_color_callback(struct gui_synclist * lists, list_get_color color_callback);
152#endif
208extern void gui_synclist_speak_item(struct gui_synclist * lists); 153extern void gui_synclist_speak_item(struct gui_synclist * lists);
209extern int gui_synclist_get_nb_items(struct gui_synclist * lists); 154extern int gui_synclist_get_nb_items(struct gui_synclist * lists);
210 155
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Jonathan Gordon
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include "lcd.h"
22#include "font.h"
23#include "sprintf.h"
24#include "string.h"
25#include "settings.h"
26#include "kernel.h"
27#include "system.h"
28#include "misc.h"
29#include "atoi.h"
30#include "viewport.h"
31#include "statusbar.h"
32#include "screen_access.h"
33
34int viewport_get_nb_lines(struct viewport *vp)
35{
36#ifdef HAVE_LCD_BITMAP
37 return vp->height/font_get(vp->font)->height;
38#else
39 (void)vp;
40 return 2;
41#endif
42}
43
44
45void viewport_set_defaults(struct viewport *vp, enum screen_type screen)
46{
47 vp->x = 0;
48 vp->width = screens[screen].width;
49
50 vp->y = global_settings.statusbar?STATUSBAR_HEIGHT:0;
51 vp->height = screens[screen].height - vp->y
52#ifdef HAS_BUTTONBAR
53 - screens[screen].has_buttonbar?BUTTONBAR_HEIGHT:0
54#endif
55 ;
56#ifdef HAVE_LCD_BITMAP
57 vp->drawmode = DRMODE_SOLID;
58 vp->font = FONT_UI; /* default to UI to discourage SYSFONT use */
59#endif
60 if (screens[screen].depth > 1)
61 {
62#ifdef HAVE_LCD_COLOR
63 vp->fg_pattern = global_settings.fg_color;
64 vp->bg_pattern = global_settings.bg_color;
65 vp->lss_pattern = global_settings.lss_color;
66 vp->lse_pattern = global_settings.lse_color;
67 vp->lst_pattern = global_settings.lst_color;
68#elif LCD_DEPTH > 1
69 vp->fg_pattern = LCD_DEFAULT_FG;
70 vp->bg_pattern = LCD_DEFAULT_BG;
71#endif
72 }
73}
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 @@
1
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
10 *
11 * Copyright (C) 2008 by Jonathan Gordon
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include "config.h"
22#include "lcd.h"
23#include "font.h"
24#include "sprintf.h"
25#include "string.h"
26#include "settings.h"
27#include "kernel.h"
28#include "system.h"
29#include "misc.h"
30#include "screen_access.h"
31
32/* return the number of text lines in the vp viewport */
33int viewport_get_nb_lines(struct viewport *vp);
34
35#define VP_ERROR 0
36#define VP_DIMENSIONS 0x1
37#define VP_COLORS 0x2
38#define VP_SELECTIONCOLORS 0x4
39/* load a viewport struct from a config string.
40 returns a combination of the above to say which were loaded ok from the string */
41int viewport_load_config(const char *config, struct viewport *vp);
42
43void 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)
125static void app_main(void) 125static void app_main(void)
126#endif 126#endif
127{ 127{
128 int i;
128 init(); 129 init();
130 FOR_NB_SCREENS(i)
131 {
132 screens[i].clear_display();
133 screens[i].update();
134 }
129 tree_gui_init(); 135 tree_gui_init();
130 root_menu(); 136 root_menu();
131} 137}
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,
297/***********************************/ 297/***********************************/
298/* BARS MENU */ 298/* BARS MENU */
299#ifdef HAVE_LCD_BITMAP 299#ifdef HAVE_LCD_BITMAP
300int statusbar_callback(int action,const struct menu_item_ex *this_item)
301{
302 (void)this_item;
303 switch (action)
304 {
305 case ACTION_EXIT_MENUITEM:
306 /* this should be changed so only the viewports are reloaded */
307 settings_apply();
308 break;
309 }
310 return action;
311}
300MENUITEM_SETTING(scrollbar_item, &global_settings.scrollbar, NULL); 312MENUITEM_SETTING(scrollbar_item, &global_settings.scrollbar, NULL);
301MENUITEM_SETTING(statusbar, &global_settings.statusbar, NULL); 313MENUITEM_SETTING(statusbar, &global_settings.statusbar, statusbar_callback);
302#if CONFIG_KEYPAD == RECORDER_PAD 314#if CONFIG_KEYPAD == RECORDER_PAD
303MENUITEM_SETTING(buttonbar, &global_settings.buttonbar, NULL); 315MENUITEM_SETTING(buttonbar, &global_settings.buttonbar, NULL);
304#endif 316#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)
951 if (global_settings.colors_file[0]) 951 if (global_settings.colors_file[0])
952 read_color_theme_file(); 952 read_color_theme_file();
953#endif 953#endif
954 954 list_init_viewports();
955} 955}
956 956
957 957
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)
311 gui_synclist_set_voice_callback(&tree_lists, tree_voice_cb); 311 gui_synclist_set_voice_callback(&tree_lists, tree_voice_cb);
312 gui_synclist_set_icon_callback(&tree_lists, &tree_get_fileicon); 312 gui_synclist_set_icon_callback(&tree_lists, &tree_get_fileicon);
313#ifdef HAVE_LCD_COLOR 313#ifdef HAVE_LCD_COLOR
314 gui_list_set_color_callback(&tree_lists, 314 gui_synclist_set_color_callback(&tree_lists, &tree_get_filecolor);
315 &tree_get_filecolor);
316#endif 315#endif
317} 316}
318 317