summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-12-20 23:34:28 +0100
committerThomas Martitz <kugel@rockbox.org>2014-01-07 14:13:40 +0100
commiteec89a90ffdd077d687914fe18a9e48028f07fb4 (patch)
tree9df85c16b973f5cb6dbf081685a14c68ef8f3e72
parent5d6974641b14ef81396e8deebcc65a87c07334e5 (diff)
downloadrockbox-eec89a90ffdd077d687914fe18a9e48028f07fb4.tar.gz
rockbox-eec89a90ffdd077d687914fe18a9e48028f07fb4.zip
lists: Adapt put_line().
This enables removing large portions of code, simplifiyng the drawing routine. All of the removed code is functionaltiy now available through put_line(). Change-Id: Ib8e61772134189a8c3c6d22345c0b45e912bea76
-rw-r--r--apps/gui/bitmap/list.c270
-rw-r--r--apps/gui/charcell/list.c67
-rw-r--r--apps/gui/list.c55
-rw-r--r--apps/gui/list.h2
4 files changed, 153 insertions, 241 deletions
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index b1fd474571..f1def9007d 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -41,8 +41,10 @@
41#include "viewport.h" 41#include "viewport.h"
42#include "statusbar-skinned.h" 42#include "statusbar-skinned.h"
43#include "debug.h" 43#include "debug.h"
44#include "line.h"
44 45
45#define ICON_PADDING 1 46#define ICON_PADDING 1
47#define ICON_PADDING_S "1"
46 48
47/* these are static to make scrolling work */ 49/* these are static to make scrolling work */
48static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS]; 50static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS];
@@ -52,10 +54,12 @@ static int y_offset;
52static bool hide_selection; 54static bool hide_selection;
53#endif 55#endif
54 56
57/* list-private helpers from the generic list.c (move to header?) */
55int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width, 58int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width,
56 int text_pos, struct screen * display, 59 int text_pos, struct screen * display,
57 struct viewport *vp); 60 struct viewport *vp);
58bool list_display_title(struct gui_synclist *list, enum screen_type screen); 61bool list_display_title(struct gui_synclist *list, enum screen_type screen);
62int list_get_nb_lines(struct gui_synclist *list, enum screen_type screen);
59 63
60void gui_synclist_scroll_stop(struct gui_synclist *lists) 64void gui_synclist_scroll_stop(struct gui_synclist *lists)
61{ 65{
@@ -87,16 +91,11 @@ static int list_icon_width(enum screen_type screen)
87 return get_icon_width(screen) + ICON_PADDING * 2; 91 return get_icon_width(screen) + ICON_PADDING * 2;
88} 92}
89 93
90static int list_icon_height(enum screen_type screen)
91{
92 return get_icon_height(screen);
93}
94
95static bool draw_title(struct screen *display, struct gui_synclist *list) 94static bool draw_title(struct screen *display, struct gui_synclist *list)
96{ 95{
97 const int screen = display->screen_type; 96 const int screen = display->screen_type;
98 int style = STYLE_DEFAULT;
99 struct viewport *title_text_vp = &title_text[screen]; 97 struct viewport *title_text_vp = &title_text[screen];
98 struct line_desc line = LINE_DESC_DEFINIT;
100 99
101 if (sb_set_title_text(list->title, list->title_icon, screen)) 100 if (sb_set_title_text(list->title, list->title_icon, screen))
102 return false; /* the sbs is handling the title */ 101 return false; /* the sbs is handling the title */
@@ -104,65 +103,46 @@ static bool draw_title(struct screen *display, struct gui_synclist *list)
104 if (!list_display_title(list, screen)) 103 if (!list_display_title(list, screen))
105 return false; 104 return false;
106 *title_text_vp = *(list->parent[screen]); 105 *title_text_vp = *(list->parent[screen]);
107 title_text_vp->height = title_text_vp->line_height; 106 line.height = list->line_height[screen];
108 107 title_text_vp->height = line.height;
109 if (list->title_icon != Icon_NOICON && global_settings.show_icons)
110 {
111 struct viewport title_icon = *title_text_vp;
112
113 title_icon.width = list_icon_width(screen);
114 title_icon.y += (title_icon.height - list_icon_height(screen)) / 2;
115 title_icon.height = list_icon_height(screen);
116 if (VP_IS_RTL(&title_icon))
117 {
118 title_icon.x += title_text_vp->width - title_icon.width;
119 }
120 else
121 {
122 title_text_vp->x += title_icon.width;
123 }
124 title_text_vp->width -= title_icon.width;
125 108
126 display->set_viewport(&title_icon);
127 screen_put_iconxy(display, ICON_PADDING, 0, list->title_icon);
128 }
129#ifdef HAVE_LCD_COLOR 109#ifdef HAVE_LCD_COLOR
130 if (list->title_color >= 0) 110 if (list->title_color >= 0)
131 { 111 line.style |= (STYLE_COLORED|list->title_color);
132 style |= (STYLE_COLORED|list->title_color);
133 }
134#endif 112#endif
113 line.scroll = true;
114
135 display->set_viewport(title_text_vp); 115 display->set_viewport(title_text_vp);
136 display->puts_scroll_style(0, 0, list->title, style); 116
117 if (list->title_icon != Icon_NOICON && global_settings.show_icons)
118 put_line(display, 0, 0, &line, "$"ICON_PADDING_S"I$t",
119 list->title_icon, list->title);
120 else
121 put_line(display, 0, 0, &line, "$t", list->title);
122
137 return true; 123 return true;
138} 124}
139 125
140void list_draw(struct screen *display, struct gui_synclist *list) 126void list_draw(struct screen *display, struct gui_synclist *list)
141{ 127{
142 struct viewport list_icons; 128 int start, end, item_offset, i;
143 int start, end, line_height, style, item_offset, i;
144 const int screen = display->screen_type; 129 const int screen = display->screen_type;
145 const int list_start_item = list->start_item[screen]; 130 const int list_start_item = list->start_item[screen];
146 const int icon_width = list_icon_width(screen);
147 const bool scrollbar_in_left = (global_settings.scrollbar == SCROLLBAR_LEFT); 131 const bool scrollbar_in_left = (global_settings.scrollbar == SCROLLBAR_LEFT);
148 const bool scrollbar_in_right = (global_settings.scrollbar == SCROLLBAR_RIGHT); 132 const bool scrollbar_in_right = (global_settings.scrollbar == SCROLLBAR_RIGHT);
149 const bool show_cursor = !global_settings.cursor_style && 133 const bool show_cursor = !global_settings.cursor_style &&
150 list->show_selection_marker; 134 list->show_selection_marker;
135 const bool have_icons = global_settings.show_icons && list->callback_get_item_icon;
151 struct viewport *parent = (list->parent[screen]); 136 struct viewport *parent = (list->parent[screen]);
152#ifdef HAVE_LCD_COLOR 137 struct line_desc linedes = LINE_DESC_DEFINIT;
153 unsigned char cur_line = 0;
154#endif
155 int icon_yoffset = 0; /* to center the icon */
156 bool show_title; 138 bool show_title;
157 struct viewport *list_text_vp = &list_text[screen]; 139 struct viewport *list_text_vp = &list_text[screen];
158 int indent = 0; 140 int indent = 0;
159 141
160 line_height = parent->line_height;
161 display->set_viewport(parent); 142 display->set_viewport(parent);
162 display->clear_viewport(); 143 display->clear_viewport();
163 display->scroll_stop_viewport(list_text_vp); 144 display->scroll_stop_viewport(list_text_vp);
164 *list_text_vp = *parent; 145 *list_text_vp = *parent;
165 list_text_vp->line_height = line_height;
166 if ((show_title = draw_title(display, list))) 146 if ((show_title = draw_title(display, list)))
167 { 147 {
168 int title_height = title_text[screen].height; 148 int title_height = title_text[screen].height;
@@ -170,7 +150,10 @@ void list_draw(struct screen *display, struct gui_synclist *list)
170 list_text_vp->height -= title_height; 150 list_text_vp->height -= title_height;
171 } 151 }
172 152
173 const int nb_lines = viewport_get_nb_lines(list_text_vp); 153 const int nb_lines = list_get_nb_lines(list, screen);
154
155 linedes.height = list->line_height[screen];
156 linedes.nlines = list->selected_size;
174 157
175 start = list_start_item; 158 start = list_start_item;
176 end = start + nb_lines; 159 end = start + nb_lines;
@@ -185,7 +168,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
185 { 168 {
186 /* make it negative for more consistent apparence when switching 169 /* make it negative for more consistent apparence when switching
187 * directions */ 170 * directions */
188 draw_offset -= line_height; 171 draw_offset -= linedes.height;
189 if (start > 0) 172 if (start > 0)
190 start--; 173 start--;
191 } 174 }
@@ -196,110 +179,71 @@ void list_draw(struct screen *display, struct gui_synclist *list)
196#endif 179#endif
197 180
198 /* draw the scrollbar if its needed */ 181 /* draw the scrollbar if its needed */
199 if (global_settings.scrollbar && nb_lines < list->nb_items) 182 if (global_settings.scrollbar != SCROLLBAR_OFF)
200 { 183 {
201 struct viewport vp = *list_text_vp; 184 /* if the scrollbar is shown the text viewport needs to shrink */
202 vp.width = SCROLLBAR_WIDTH; 185 if (nb_lines < list->nb_items)
203 vp.height = line_height * nb_lines;
204 vp.x = parent->x;
205 list_text_vp->width -= SCROLLBAR_WIDTH;
206 if (scrollbar_in_left)
207 list_text_vp->x += SCROLLBAR_WIDTH;
208 else
209 vp.x += list_text_vp->width;
210 display->set_viewport(&vp);
211 gui_scrollbar_draw(display,
212 (scrollbar_in_left? 0: 1), 0, SCROLLBAR_WIDTH-1, vp.height,
213 list->nb_items, list_start_item, list_start_item + nb_lines,
214 VERTICAL);
215 }
216 else if (show_title)
217 {
218 /* shift everything a bit in relation to the title... */
219 if (!VP_IS_RTL(list_text_vp) && scrollbar_in_left)
220 { 186 {
187 struct viewport vp = *list_text_vp;
188 vp.width = SCROLLBAR_WIDTH;
189 vp.height = linedes.height * nb_lines;
221 list_text_vp->width -= SCROLLBAR_WIDTH; 190 list_text_vp->width -= SCROLLBAR_WIDTH;
222 list_text_vp->x += SCROLLBAR_WIDTH; 191 if (scrollbar_in_right)
192 vp.x += list_text_vp->width;
193 else /* left */
194 list_text_vp->x += SCROLLBAR_WIDTH;
195 display->set_viewport(&vp);
196 gui_scrollbar_draw(display,
197 (scrollbar_in_left? 0: 1), 0, SCROLLBAR_WIDTH-1, vp.height,
198 list->nb_items, list_start_item, list_start_item + nb_lines,
199 VERTICAL);
223 } 200 }
201 /* shift everything a bit in relation to the title */
202 else if (!VP_IS_RTL(list_text_vp) && scrollbar_in_left)
203 indent += SCROLLBAR_WIDTH;
224 else if (VP_IS_RTL(list_text_vp) && scrollbar_in_right) 204 else if (VP_IS_RTL(list_text_vp) && scrollbar_in_right)
225 { 205 indent += SCROLLBAR_WIDTH;
226 list_text_vp->width -= SCROLLBAR_WIDTH;
227 }
228 }
229
230 /* setup icon placement */
231 list_icons = *list_text_vp;
232 int icon_count = (list->callback_get_item_icon != NULL) ? 1 : 0;
233 if (show_cursor)
234 icon_count++;
235 if (icon_count)
236 {
237 list_icons.width = icon_width * icon_count;
238 list_text_vp->width -= list_icons.width + ICON_PADDING;
239 if (VP_IS_RTL(&list_icons))
240 list_icons.x += list_text_vp->width + ICON_PADDING;
241 else
242 list_text_vp->x += list_icons.width + ICON_PADDING;
243 icon_yoffset = (line_height - list_icon_height(screen)) / 2;
244 } 206 }
245 207
246 for (i=start; i<end && i<list->nb_items; i++) 208 for (i=start; i<end && i<list->nb_items; i++)
247 { 209 {
248 /* do the text */ 210 /* do the text */
211 enum themable_icons icon;
249 unsigned const char *s; 212 unsigned const char *s;
250 char entry_buffer[MAX_PATH]; 213 char entry_buffer[MAX_PATH];
251 unsigned char *entry_name; 214 unsigned char *entry_name;
252 int text_pos = 0; 215 int text_pos = 0;
253 int line = i - start; 216 int line = i - start;
254 indent = 0; 217 int line_indent = 0;
218 int style = STYLE_DEFAULT;
219 bool is_selected = false;
220 icon = list->callback_get_item_icon ?
221 list->callback_get_item_icon(i, list->data) : Icon_NOICON;
255 s = list->callback_get_item_name(i, list->data, entry_buffer, 222 s = list->callback_get_item_name(i, list->data, entry_buffer,
256 sizeof(entry_buffer)); 223 sizeof(entry_buffer));
257 entry_name = P2STR(s); 224 entry_name = P2STR(s);
258 225
259 while (*entry_name == '\t') 226 while (*entry_name == '\t')
260 { 227 {
261 indent++; 228 line_indent++;
262 entry_name++; 229 entry_name++;
263 } 230 }
264 if (indent) 231 if (line_indent)
265 { 232 {
266 if (icon_width) 233 if (global_settings.show_icons)
267 indent *= icon_width; 234 line_indent *= list_icon_width(screen);
268 else 235 else
269 indent *= display->getcharwidth(); 236 line_indent *= display->getcharwidth();
270
271 if (VP_IS_RTL(&list_icons))
272 {
273 list_icons.x -= indent;
274 }
275 else
276 {
277 list_icons.x += indent;
278 list_text_vp->x += indent;
279 }
280 list_text_vp->width -= indent;
281 } 237 }
238 line_indent += indent;
282 239
283 display->set_viewport(list_text_vp); 240 display->set_viewport(list_text_vp);
284 style = STYLE_DEFAULT;
285 /* position the string at the correct offset place */ 241 /* position the string at the correct offset place */
286 int item_width,h; 242 int item_width,h;
287 display->getstringsize(entry_name, &item_width, &h); 243 display->getstringsize(entry_name, &item_width, &h);
288 item_offset = gui_list_get_item_offset(list, item_width, text_pos, 244 item_offset = gui_list_get_item_offset(list, item_width, text_pos,
289 display, list_text_vp); 245 display, list_text_vp);
290 246
291#ifdef HAVE_LCD_COLOR
292 /* if the list has a color callback */
293 if (list->callback_get_item_color)
294 {
295 int color = list->callback_get_item_color(i, list->data);
296 /* if color selected */
297 if (color >= 0)
298 {
299 style |= STYLE_COLORED|color;
300 }
301 }
302#endif
303 /* draw the selected line */ 247 /* draw the selected line */
304 if( 248 if(
305#ifdef HAVE_TOUCHSCREEN 249#ifdef HAVE_TOUCHSCREEN
@@ -327,73 +271,53 @@ void list_draw(struct screen *display, struct gui_synclist *list)
327 { 271 {
328 /* Display colour line selector */ 272 /* Display colour line selector */
329 style = STYLE_COLORBAR; 273 style = STYLE_COLORBAR;
274 linedes.text_color = global_settings.lst_color;
275 linedes.line_color = global_settings.lss_color;
330 } 276 }
331 else if (global_settings.cursor_style == 3) 277 else if (global_settings.cursor_style == 3)
332 { 278 {
333 /* Display gradient line selector */ 279 /* Display gradient line selector */
334 style = STYLE_GRADIENT; 280 style = STYLE_GRADIENT;
335 281 linedes.text_color = global_settings.lst_color;
336 /* Make the lcd driver know how many lines the gradient should 282 linedes.line_color = global_settings.lss_color;
337 cover and current line number */ 283 linedes.line_end_color = global_settings.lse_color;
338 /* number of selected lines */
339 style |= NUMLN_PACK(list->selected_size);
340 /* current line number, zero based */
341 style |= CURLN_PACK(cur_line);
342 cur_line++;
343 } 284 }
344#endif 285#endif
345 /* if the text is smaller than the viewport size */ 286 is_selected = true;
346 if (item_offset> item_width - (list_text_vp->width - text_pos))
347 {
348 /* don't scroll */
349 display->puts_style_xyoffset(0, line, entry_name,
350 style, item_offset, draw_offset);
351 }
352 else
353 {
354 display->puts_scroll_style_xyoffset(0, line, entry_name,
355 style, item_offset, draw_offset);
356 }
357 } 287 }
358 else 288
359 { 289#ifdef HAVE_LCD_COLOR
360 if (list->scroll_all) 290 /* if the list has a color callback */
361 display->puts_scroll_style_xyoffset(0, line, entry_name, 291 if (list->callback_get_item_color)
362 style, item_offset, draw_offset);
363 else
364 display->puts_style_xyoffset(0, line, entry_name,
365 style, item_offset, draw_offset);
366 }
367 /* do the icon */
368 display->set_viewport(&list_icons);
369 if (list->callback_get_item_icon != NULL)
370 {
371 int xoff = show_cursor ? list_icon_width(screen) : ICON_PADDING;
372 screen_put_iconxy(display, xoff,
373 line*line_height + draw_offset + icon_yoffset,
374 list->callback_get_item_icon(i, list->data));
375 }
376 /* do the cursor */
377 if (show_cursor && i >= list->selected_item &&
378 i < list->selected_item + list->selected_size)
379 {
380 screen_put_iconxy(display, ICON_PADDING,
381 line*line_height + draw_offset + icon_yoffset,
382 Icon_Cursor);
383 }
384 if (indent)
385 { 292 {
386 if (VP_IS_RTL(&list_icons)) 293 int c = list->callback_get_item_color(i, list->data);
387 { 294 if (c >= 0)
388 list_icons.x += indent; 295 { /* if color selected */
389 } 296 linedes.text_color = c;
390 else 297 style |= STYLE_COLORED;
391 {
392 list_icons.x -= indent;
393 list_text_vp->x -= indent;
394 } 298 }
395 list_text_vp->width += indent;
396 } 299 }
300#endif
301
302 linedes.style = style;
303 linedes.scroll = is_selected ?: list->scroll_all;
304 linedes.line = i % list->selected_size;
305
306 /* the list can have both, one of or neither of cursor and item icons,
307 * if both don't apply icon padding twice between the icons */
308 if (show_cursor && have_icons)
309 put_line(display, 0, line * linedes.height + draw_offset,
310 &linedes, "$*s$"ICON_PADDING_S"I$i$"ICON_PADDING_S"s$*t",
311 line_indent, is_selected ? Icon_Cursor : Icon_NOICON,
312 icon, item_offset, entry_name);
313 else if (show_cursor || have_icons)
314 put_line(display, 0, line * linedes.height + draw_offset,
315 &linedes, "$*s$"ICON_PADDING_S"I$*t", line_indent,
316 show_cursor ? (is_selected ? Icon_Cursor:Icon_NOICON):icon,
317 item_offset, entry_name);
318 else
319 put_line(display, 0, line * linedes.height + draw_offset,
320 &linedes, "$*s$*t", line_indent, item_offset, entry_name);
397 } 321 }
398 display->set_viewport(parent); 322 display->set_viewport(parent);
399 display->update_viewport(); 323 display->update_viewport();
@@ -417,13 +341,13 @@ static int scrollbar_scroll(struct gui_synclist * gui_list,
417 int y) 341 int y)
418{ 342{
419 const int screen = screens[SCREEN_MAIN].screen_type; 343 const int screen = screens[SCREEN_MAIN].screen_type;
420 const int nb_lines = viewport_get_nb_lines(&list_text[screen]); 344 const int nb_lines = list_get_nb_lines(gui_list, screen);
421 345
422 if (nb_lines < gui_list->nb_items) 346 if (nb_lines < gui_list->nb_items)
423 { 347 {
424 /* scrollbar scrolling is still line based */ 348 /* scrollbar scrolling is still line based */
425 y_offset = 0; 349 y_offset = 0;
426 int scrollbar_size = nb_lines*gui_list->parent[screen]->line_height; 350 int scrollbar_size = nb_lines*gui_list->line_height[screen];
427 int actual_y = y - list_text[screen].y; 351 int actual_y = y - list_text[screen].y;
428 352
429 int new_selection = (actual_y * gui_list->nb_items) 353 int new_selection = (actual_y * gui_list->nb_items)
@@ -547,8 +471,8 @@ static bool swipe_scroll(struct gui_synclist * gui_list, int difference)
547{ 471{
548 /* fixme */ 472 /* fixme */
549 const enum screen_type screen = screens[SCREEN_MAIN].screen_type; 473 const enum screen_type screen = screens[SCREEN_MAIN].screen_type;
550 const int nb_lines = viewport_get_nb_lines(&list_text[screen]); 474 const int nb_lines = list_get_nb_lines(gui_list, screen);
551 const int line_height = gui_list->parent[0]->line_height; 475 const int line_height = gui_list->line_height[screen];
552 476
553 if (UNLIKELY(scroll_begin_threshold == 0)) 477 if (UNLIKELY(scroll_begin_threshold == 0))
554 scroll_begin_threshold = touchscreen_get_scroll_threshold(); 478 scroll_begin_threshold = touchscreen_get_scroll_threshold();
@@ -752,7 +676,7 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * list)
752 676
753 screen = SCREEN_MAIN; 677 screen = SCREEN_MAIN;
754 parent = list->parent[screen]; 678 parent = list->parent[screen];
755 line_height = list->parent[screen]->line_height; 679 line_height = list->line_height[screen];
756 list_start_item = list->start_item[screen]; 680 list_start_item = list->start_item[screen];
757 /* start with getting the action code and finding the click location */ 681 /* start with getting the action code and finding the click location */
758 action = action_get_touchscreen_press(&x, &y); 682 action = action_get_touchscreen_press(&x, &y);
diff --git a/apps/gui/charcell/list.c b/apps/gui/charcell/list.c
index 753b8ff853..cbee8b0d9d 100644
--- a/apps/gui/charcell/list.c
+++ b/apps/gui/charcell/list.c
@@ -49,9 +49,8 @@ void gui_synclist_scroll_stop(struct gui_synclist *lists)
49 49
50void list_draw(struct screen *display, struct gui_synclist *gui_list) 50void list_draw(struct screen *display, struct gui_synclist *gui_list)
51{ 51{
52 int text_pos;
53 bool draw_icons = (gui_list->callback_get_item_icon != NULL); 52 bool draw_icons = (gui_list->callback_get_item_icon != NULL);
54 bool draw_cursor; 53 bool selected;
55 int i; 54 int i;
56 int start, end; 55 int start, end;
57 56
@@ -61,12 +60,13 @@ void list_draw(struct screen *display, struct gui_synclist *gui_list)
61 start = 0; 60 start = 0;
62 end = display->getnblines(); 61 end = display->getnblines();
63 62
64 /* Adjust the position of icon, cursor, text for the list */ 63 struct line_desc desc = {
65 draw_cursor = true; 64 .height = -1,
66 if(draw_icons) 65 .text_color = 1,
67 text_pos = 2; /* here it's in chars */ 66 .line_color = 1,
68 else 67 .line_end_color = 1,
69 text_pos = 1; 68 .style = STYLE_DEFAULT
69 };
70 70
71 for (i = start; i < end; i++) 71 for (i = start; i < end; i++)
72 { 72 {
@@ -85,43 +85,26 @@ void list_draw(struct screen *display, struct gui_synclist *gui_list)
85 sizeof(entry_buffer)); 85 sizeof(entry_buffer));
86 entry_name = P2STR(s); 86 entry_name = P2STR(s);
87 87
88 if (gui_list->show_selection_marker &&
89 current_item >= gui_list->selected_item &&
90 current_item < gui_list->selected_item + gui_list->selected_size)
91 selected = true; /* The selected item must be displayed scrolling */
92 else
93 selected = false;
88 94
89 if(gui_list->show_selection_marker && 95 desc.nlines = gui_list->selected_size,
90 current_item >= gui_list->selected_item && 96 desc.line = gui_list->selected_size > 1 ? i : 0,
91 current_item < gui_list->selected_item + gui_list->selected_size) 97 desc.scroll = selected ? true : gui_list->scroll_all;
92 {/* The selected item must be displayed scrolling */
93 display->puts_scroll(text_pos, i, entry_name);
94 98
95 if (draw_cursor) 99 if (draw_icons)
96 { 100 put_line(display, 0, i, &desc, "$i$i$t",
97 screen_put_icon_with_offset(display, 0, i, 101 selected ? Icon_Cursor : Icon_NOICON,
98 (draw_scrollbar || SHOW_LIST_TITLE)? 102 gui_list->callback_get_item_icon(current_item, gui_list->data),
99 SCROLLBAR_WIDTH: 0, 103 entry_name);
100 0, Icon_Cursor);
101 }
102 }
103 else 104 else
104 {/* normal item */ 105 put_line(display, 0, i, &desc, "$i$t",
105 if(gui_list->scroll_all) 106 selected ? Icon_Cursor : Icon_NOICON,
106 { 107 entry_name);
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 } 108 }
126 109
127 display->update_viewport(); 110 display->update_viewport();
diff --git a/apps/gui/list.c b/apps/gui/list.c
index 27032378c3..c393340c57 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -78,25 +78,6 @@ void list_init(void)
78 add_event(GUI_EVENT_THEME_CHANGED, false, list_force_reinit); 78 add_event(GUI_EVENT_THEME_CHANGED, false, list_force_reinit);
79} 79}
80 80
81#ifdef HAVE_TOUCHSCREEN
82static int line_height_from_lcd_dpi(const struct viewport *vp)
83{
84 /* the 4/12 factor is designed for reasonable item size on a 160dpi screen */
85 return MAX(lcd_get_dpi()*4/12, (int)font_get(vp->font)->height);
86}
87#endif
88
89static int list_line_height(const struct viewport *vp)
90{
91#ifdef HAVE_TOUCHSCREEN
92 if (global_settings.list_line_padding == -1)
93 return line_height_from_lcd_dpi(vp);
94 return font_get(vp->font)->height + global_settings.list_line_padding;
95#else
96 return font_get(vp->font)->height;
97#endif
98}
99
100static void list_init_viewports(struct gui_synclist *list) 81static void list_init_viewports(struct gui_synclist *list)
101{ 82{
102 bool parent_used = (*list->parent == &parent[SCREEN_MAIN]); 83 bool parent_used = (*list->parent == &parent[SCREEN_MAIN]);
@@ -127,29 +108,50 @@ static struct viewport parent[NB_SCREENS] =
127#endif 108#endif
128 109
129#ifdef HAVE_LCD_BITMAP 110#ifdef HAVE_LCD_BITMAP
111static int list_nb_lines(struct gui_synclist *list, enum screen_type screen)
112{
113 struct viewport *vp = list->parent[screen];
114 return vp->height / list->line_height[screen];
115}
116
130bool list_display_title(struct gui_synclist *list, enum screen_type screen) 117bool list_display_title(struct gui_synclist *list, enum screen_type screen)
131{ 118{
132 return list->title != NULL && 119 return list->title != NULL &&
133 !sb_set_title_text(list->title, list->title_icon, screen) && 120 !sb_set_title_text(list->title, list->title_icon, screen) &&
134 viewport_get_nb_lines(list->parent[screen]) > 2; 121 list_nb_lines(list, screen) > 2;
135} 122}
136 123
137static int list_get_nb_lines(struct gui_synclist *list, enum screen_type screen) 124int list_get_nb_lines(struct gui_synclist *list, enum screen_type screen)
138{ 125{
139 struct viewport *vp = list->parent[screen];
140 int lines = skinlist_get_line_count(screen, list); 126 int lines = skinlist_get_line_count(screen, list);
141 if (lines < 0) 127 if (lines < 0)
142 { 128 {
143 lines = viewport_get_nb_lines(vp); 129 lines = list_nb_lines(list, screen);
144 if (list_display_title(list, screen)) 130 if (list_display_title(list, screen))
145 lines -= 1; 131 lines -= 1;
146 } 132 }
147 return lines; 133 return lines;
148} 134}
135
136void list_init_item_height(struct gui_synclist *list, enum screen_type screen)
137{
138 struct viewport *vp = list->parent[screen];
139#ifdef HAVE_TOUCHSCREEN
140 /* the 4/12 factor is designed for reasonable item size on a 160dpi screen */
141 if (global_settings.list_line_padding == -1)
142 list->line_height[screen] = MAX(lcd_get_dpi()*4/12, (int)font_get(vp->font)->height);
143 else
144 list->line_height[screen] = font_get(vp->font)->height + global_settings.list_line_padding;
145#else
146 list->line_height[screen] = font_get(vp->font)->height;
147#endif
148}
149
149#else 150#else
150#define list_display_title(l, i) false 151#define list_display_title(l, i) false
151#define list_get_nb_lines(list, screen) \ 152#define list_get_nb_lines(list, screen) \
152 viewport_get_nb_lines((list)->parent[(screen)]); 153 viewport_get_nb_lines((list)->parent[(screen)]);
154#define list_init_item_height(l, i)
153#endif 155#endif
154 156
155/* 157/*
@@ -187,6 +189,8 @@ void gui_synclist_init(struct gui_synclist * gui_list,
187 gui_list->parent[i] = &parent[i]; 189 gui_list->parent[i] = &parent[i];
188 } 190 }
189 list_init_viewports(gui_list); 191 list_init_viewports(gui_list);
192 FOR_NB_SCREENS(i)
193 list_init_item_height(gui_list, i);
190 gui_list->limit_scroll = false; 194 gui_list->limit_scroll = false;
191 gui_list->data = data; 195 gui_list->data = data;
192 gui_list->scroll_all = scroll_all; 196 gui_list->scroll_all = scroll_all;
@@ -253,6 +257,8 @@ void gui_synclist_draw(struct gui_synclist *gui_list)
253 if (list_is_dirty(gui_list)) 257 if (list_is_dirty(gui_list))
254 { 258 {
255 list_init_viewports(gui_list); 259 list_init_viewports(gui_list);
260 FOR_NB_SCREENS(i)
261 list_init_item_height(gui_list, i);
256 gui_synclist_select_item(gui_list, gui_list->selected_item); 262 gui_synclist_select_item(gui_list, gui_list->selected_item);
257 } 263 }
258 FOR_NB_SCREENS(i) 264 FOR_NB_SCREENS(i)
@@ -502,9 +508,6 @@ void gui_synclist_set_viewport_defaults(struct viewport *vp,
502 enum screen_type screen) 508 enum screen_type screen)
503{ 509{
504 viewport_set_defaults(vp, screen); 510 viewport_set_defaults(vp, screen);
505#ifdef HAVE_LCD_BITMAP
506 vp->line_height = list_line_height(vp);
507#endif
508#ifdef HAVE_BUTTONBAR 511#ifdef HAVE_BUTTONBAR
509 if (screens[screen].has_buttonbar) 512 if (screens[screen].has_buttonbar)
510 vp->height -= BUTTONBAR_HEIGHT; 513 vp->height -= BUTTONBAR_HEIGHT;
diff --git a/apps/gui/list.h b/apps/gui/list.h
index 8980573aa3..0f2f51a424 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -100,6 +100,8 @@ struct gui_synclist
100 int start_item[NB_SCREENS]; /* the item that is displayed at the top of the screen */ 100 int start_item[NB_SCREENS]; /* the item that is displayed at the top of the screen */
101 /* the number of lines that are selected at the same time */ 101 /* the number of lines that are selected at the same time */
102 int selected_size; 102 int selected_size;
103 /* the number of pixels each line occupies (including optional padding on touchscreen */
104 int line_height[NB_SCREENS];
103#ifdef HAVE_LCD_BITMAP 105#ifdef HAVE_LCD_BITMAP
104 int offset_position[NB_SCREENS]; /* the list's screen scroll placement in pixels */ 106 int offset_position[NB_SCREENS]; /* the list's screen scroll placement in pixels */
105#endif 107#endif