diff options
-rw-r--r-- | apps/gui/bitmap/list.c | 270 | ||||
-rw-r--r-- | apps/gui/charcell/list.c | 67 | ||||
-rw-r--r-- | apps/gui/list.c | 55 | ||||
-rw-r--r-- | apps/gui/list.h | 2 |
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 */ |
48 | static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS]; | 50 | static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS]; |
@@ -52,10 +54,12 @@ static int y_offset; | |||
52 | static bool hide_selection; | 54 | static bool hide_selection; |
53 | #endif | 55 | #endif |
54 | 56 | ||
57 | /* list-private helpers from the generic list.c (move to header?) */ | ||
55 | int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width, | 58 | int 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); |
58 | bool list_display_title(struct gui_synclist *list, enum screen_type screen); | 61 | bool list_display_title(struct gui_synclist *list, enum screen_type screen); |
62 | int list_get_nb_lines(struct gui_synclist *list, enum screen_type screen); | ||
59 | 63 | ||
60 | void gui_synclist_scroll_stop(struct gui_synclist *lists) | 64 | void 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 | ||
90 | static int list_icon_height(enum screen_type screen) | ||
91 | { | ||
92 | return get_icon_height(screen); | ||
93 | } | ||
94 | |||
95 | static bool draw_title(struct screen *display, struct gui_synclist *list) | 94 | static 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 | ||
140 | void list_draw(struct screen *display, struct gui_synclist *list) | 126 | void 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 | ||
50 | void list_draw(struct screen *display, struct gui_synclist *gui_list) | 50 | void 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 | ||
82 | static 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 | |||
89 | static 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 | |||
100 | static void list_init_viewports(struct gui_synclist *list) | 81 | static 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 |
111 | static 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 | |||
130 | bool list_display_title(struct gui_synclist *list, enum screen_type screen) | 117 | bool 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 | ||
137 | static int list_get_nb_lines(struct gui_synclist *list, enum screen_type screen) | 124 | int 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 | |||
136 | void 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 |