summaryrefslogtreecommitdiff
path: root/apps/gui/bitmap
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2008-03-05 09:58:30 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2008-03-05 09:58:30 +0000
commit0e5cec2d187dbded9b3c36dbcfd1469d00fe47af (patch)
treeab02e321e04ebfb4fb2e0a5327b5443a10761176 /apps/gui/bitmap
parent8232e1a7c8d7cfaa16e3c8283fdb6d5a46aaf577 (diff)
downloadrockbox-0e5cec2d187dbded9b3c36dbcfd1469d00fe47af.tar.gz
rockbox-0e5cec2d187dbded9b3c36dbcfd1469d00fe47af.zip
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
Diffstat (limited to 'apps/gui/bitmap')
-rw-r--r--apps/gui/bitmap/list.c276
1 files changed, 276 insertions, 0 deletions
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